def _eval_expand_multinomial(self, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" base, exp = self.args result = self if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return result else: radical, result = self.func(base, exp - n), [] expanded_base_n = self.func(base, n) if expanded_base_n.is_Pow: expanded_base_n = \ expanded_base_n._eval_expand_multinomial() for term in Add.make_args(expanded_base_n): result.append(term*radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for b in base.args: if b.is_Order: order_terms.append(b) else: other_terms.append(b) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) o = Add(*order_terms) if n == 2: return expand_multinomial(f**n, deep=False) + n*f*o else: g = expand_multinomial(f**(n - 1), deep=False) return expand_mul(f*g, deep=False) + n*g*o if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = self.func(a.q * b.q, n) a, b = a.p*b.q, a.q*b.p else: k = self.func(a.q, n) a, b = a.p, a.q*b elif not b.is_Integer: k = self.func(b.q, n) a, b = a*b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a*c - b*d, b*c + a*d n -= 1 a, b = a*a - b*b, 2*a*b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I*d else: return Integer(c)/k + I*d/k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients from sympy.polys.polyutils import basic_from_dict expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. return basic_from_dict(expansion_dict, *p) else: if n == 2: return Add(*[f*g for f in base.args for g in base.args]) else: multi = (base**(n - 1))._eval_expand_multinomial() if multi.is_Add: return Add(*[f*g for f in base.args for g in multi.args]) else: # XXX can this ever happen if base was an Add? return Add(*[f*multi for f in base.args]) elif (exp.is_Rational and exp.p < 0 and base.is_Add and abs(exp.p) > exp.q): return 1 / self.func(base, -exp)._eval_expand_multinomial() elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= self.func(base, term) else: tail += term return coeff * self.func(base, tail) else: return result
def _eval_expand_multinomial(self, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" base, exp = self.args result = self if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return result else: radical, result = Pow(base, exp - n), [] expanded_base_n = Pow(base, n) if expanded_base_n.is_Pow: expanded_base_n = \ expanded_base_n._eval_expand_multinomial() for term in Add.make_args(expanded_base_n): result.append(term*radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for b in base.args: if b.is_Order: order_terms.append(b) else: other_terms.append(b) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) o = Add(*order_terms) if n == 2: return expand_multinomial(f**n, deep=False) + n*f*o else: g = expand_multinomial(f**(n - 1), deep=False) return expand_mul(f*g, deep=False) + n*g*o if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = Pow(a.q * b.q, n) a, b = a.p*b.q, a.q*b.p else: k = Pow(a.q, n) a, b = a.p, a.q*b elif not b.is_Integer: k = Pow(b.q, n) a, b = a*b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a*c - b*d, b*c + a*d n -= 1 a, b = a*a - b*b, 2*a*b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I*d else: return Integer(c)/k + I*d/k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients from sympy.polys.polyutils import basic_from_dict expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. return basic_from_dict(expansion_dict, *p) else: if n == 2: return Add(*[f*g for f in base.args for g in base.args]) else: multi = (base**(n - 1))._eval_expand_multinomial() if multi.is_Add: return Add(*[f*g for f in base.args for g in multi.args]) else: # XXX can this ever happen if base was an Add? return Add(*[f*multi for f in base.args]) elif (exp.is_Rational and exp.p < 0 and base.is_Add and abs(exp.p) > exp.q): return 1 / Pow(base, -exp)._eval_expand_multinomial() elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= Pow(base, term) else: tail += term return coeff * Pow(base, tail) else: return result
def _eval_expand_multinomial(self, deep=True, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" if deep: b = self.base.expand(deep=deep, **hints) e = self.exp.expand(deep=deep, **hints) else: b = self.base e = self.exp if b is None: base = self.base else: base = b if e is None: exp = self.exp else: exp = e if e is not None or b is not None: result = Pow(base, exp) if result.is_Pow: base, exp = result.base, result.exp else: return result else: result = None if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return Pow(base, exp) else: radical, result = Pow(base, exp - n), [] for term in Add.make_args( Pow(base, n)._eval_expand_multinomial(deep=False)): result.append(term * radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for order in base.args: if order.is_Order: order_terms.append(order) else: other_terms.append(order) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) g = (f**(n - 1)).expand() return (f * g).expand() + n * g * Add(*order_terms) if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = Pow(a.q * b.q, n) a, b = a.p * b.q, a.q * b.p else: k = Pow(a.q, n) a, b = a.p, a.q * b elif not b.is_Integer: k = Pow(b.q, n) a, b = a * b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a * c - b * d, b * c + a * d n -= 1 a, b = a * a - b * b, 2 * a * b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I * d else: return Integer(c) / k + I * d / k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. # An elegant way would be to use Poly, but unfortunately it is # slower than the direct method below, so it is commented out: #b = {} #for k in expansion_dict: # b[k] = Integer(expansion_dict[k]) #return Poly(b, *p).as_expr() from sympy.polys.polyutils import basic_from_dict result = basic_from_dict(expansion_dict, *p) return result else: if n == 2: return Add(*[f * g for f in base.args for g in base.args]) else: multi = (base**(n - 1))._eval_expand_multinomial(deep=False) if multi.is_Add: return Add( *[f * g for f in base.args for g in multi.args]) else: return Add(*[f * multi for f in base.args]) elif exp.is_Rational and exp.p < 0 and base.is_Add and abs( exp.p) > exp.q: return 1 / Pow(base, -exp)._eval_expand_multinomial(deep=False) elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= Pow(base, term) else: tail += term return coeff * Pow(base, tail) else: return result
def to_sympy(self, a): """Convert `a` to a SymPy object. """ return (basic_from_dict(a.numer().to_sympy_dict(), *self.gens) / basic_from_dict(a.denom().to_sympy_dict(), *self.gens))
def to_sympy(self, a): """Convert `a` to a SymPy object. """ return basic_from_dict(a.to_sympy_dict(), *self.gens)
def _eval_expand_multinomial(self, deep=True, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" if deep: b = self.base.expand(deep=deep, **hints) e = self.exp.expand(deep=deep, **hints) else: b = self.base e = self.exp if b is None: base = self.base else: base = b if e is None: exp = self.exp else: exp = e if e is not None or b is not None: result = Pow(base, exp) if result.is_Pow: base, exp = result.base, result.exp else: return result else: result = None if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return Pow(base, exp) else: radical, result = Pow(base, exp - n), [] for term in Add.make_args(Pow(base, n)._eval_expand_multinomial(deep=False)): result.append(term*radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for order in base.args: if order.is_Order: order_terms.append(order) else: other_terms.append(order) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) g = (f**(n-1)).expand() return (f*g).expand() + n*g*Add(*order_terms) if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = Pow(a.q * b.q, n) a, b = a.p*b.q, a.q*b.p else: k = Pow(a.q, n) a, b = a.p, a.q*b elif not b.is_Integer: k = Pow(b.q, n) a, b = a*b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a*c-b*d, b*c+a*d n -= 1 a, b = a*a-b*b, 2*a*b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I*d else: return Integer(c)/k + I*d/k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. # An elegant way would be to use Poly, but unfortunately it is # slower than the direct method below, so it is commented out: #b = {} #for k in expansion_dict: # b[k] = Integer(expansion_dict[k]) #return Poly(b, *p).as_expr() from sympy.polys.polyutils import basic_from_dict result = basic_from_dict(expansion_dict, *p) return result else: if n == 2: return Add(*[f*g for f in base.args for g in base.args]) else: multi = (base**(n-1))._eval_expand_multinomial(deep=False) if multi.is_Add: return Add(*[f*g for f in base.args for g in multi.args]) else: return Add(*[f*multi for f in base.args]) elif exp.is_Rational and exp.p < 0 and base.is_Add and abs(exp.p) > exp.q: return 1 / Pow(base, -exp)._eval_expand_multinomial(deep=False) elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= Pow(base, term) else: tail += term return coeff * Pow(base, tail) else: return result