def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False) arg = x*(2*x + 4*y) garg = 2*x*(x + 2*y) assert gcd_terms(arg) == garg assert gcd_terms(sin(arg)) == sin(garg) # issue 3040-like alpha, alpha1, alpha2, alpha3 = symbols('alpha:4') a = alpha**2 - alpha*x**2 + alpha + x**3 - x*(alpha + 1) rep = (alpha, (1 + sqrt(5))/2 + alpha1*x + alpha2*x**2 + alpha3*x**3) s = (a/(x - alpha)).subs(*rep).series(x, 0, 1) assert simplify(collect(s, x)) == -sqrt(5)/2 - S(3)/2 + O(x)
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False) arg = x*(2*x + 4*y) garg = 2*x*(x + 2*y) assert gcd_terms(arg) == garg assert gcd_terms(sin(arg)) == sin(garg) # issue 3040-like alpha, alpha1, alpha2, alpha3 = symbols('alpha:4') a = alpha**2 - alpha*x**2 + alpha + x**3 - x*(alpha + 1) rep = (alpha, (1 + sqrt(5))/2 + alpha1*x + alpha2*x**2 + alpha3*x**3) s = (a/(x - alpha)).subs(*rep).series(x, 0, 1) assert simplify(collect(s, x)) == -sqrt(5)/2 - S(3)/2 + O(x) # issue 2818 assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1) assert _gcd_terms([2*x + 4]) == (2, x + 2, 1)
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + \ (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((Rational(6, 5)) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == \ ((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1) newf = (Rational(6, 5)) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms(f) == newf args = Add.make_args(f) # non-Basic sequences of terms treated as terms of Add assert gcd_terms(list(args)) == newf assert gcd_terms(tuple(args)) == newf assert gcd_terms(set(args)) == newf # but a Basic sequence is treated as a container assert gcd_terms(Tuple(*args)) != newf assert gcd_terms(Basic(Tuple(1, 3*y + 3*x*y), Tuple(1, 3))) == \ Basic((1, 3*y*(x + 1)), (1, 3)) # but we shouldn't change keys of a dictionary or some may be lost assert gcd_terms(Dict((x*(1 + y), 2), (x + x*y, y + x*y))) == \ Dict({x*(y + 1): 2, x + x*y: y*(1 + x)}) assert gcd_terms((2 * x + 2)**3 + (2 * x + 2)**2) == 4 * (x + 1)**2 * (2 * x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2 * x) == Mul(2, 1 + x, evaluate=False) arg = x * (2 * x + 4 * y) garg = 2 * x * (x + 2 * y) assert gcd_terms(arg) == garg assert gcd_terms(sin(arg)) == sin(garg) # issue 6139-like alpha, alpha1, alpha2, alpha3 = symbols('alpha:4') a = alpha**2 - alpha * x**2 + alpha + x**3 - x * (alpha + 1) rep = (alpha, (1 + sqrt(5)) / 2 + alpha1 * x + alpha2 * x**2 + alpha3 * x**3) s = (a / (x - alpha)).subs(*rep).series(x, 0, 1) assert simplify(collect(s, x)) == -sqrt(5) / 2 - Rational(3, 2) + O(x) # issue 5917 assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1) assert _gcd_terms([2 * x + 4]) == (2, x + 2, 1) eq = x / (x + 1 / x) assert gcd_terms(eq, fraction=False) == eq eq = x / 2 / y + 1 / x / y assert gcd_terms(eq, fraction=True, clear=True) == \ (x**2 + 2)/(2*x*y) assert gcd_terms(eq, fraction=True, clear=False) == \ (x**2/2 + 1)/(x*y) assert gcd_terms(eq, fraction=False, clear=True) == \ (x + 2/x)/(2*y) assert gcd_terms(eq, fraction=False, clear=False) == \ (x/2 + 1/x)/y
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + \ (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == \ ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) newf = (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(f) == newf args = Add.make_args(f) # non-Basic sequences of terms treated as terms of Add assert gcd_terms(list(args)) == newf assert gcd_terms(tuple(args)) == newf assert gcd_terms(set(args)) == newf # but a Basic sequence is treated as a container assert gcd_terms(Tuple(*args)) != newf assert gcd_terms(Basic(Tuple(1, 3*y + 3*x*y), Tuple(1, 3))) == \ Basic((1, 3*y*(x + 1)), (1, 3)) # but we shouldn't change keys of a dictionary or some may be lost assert gcd_terms(Dict((x*(1 + y), 2), (x + x*y, y + x*y))) == \ Dict({x*(y + 1): 2, x + x*y: y*(1 + x)}) assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False) arg = x*(2*x + 4*y) garg = 2*x*(x + 2*y) assert gcd_terms(arg) == garg assert gcd_terms(sin(arg)) == sin(garg) # issue 6139-like alpha, alpha1, alpha2, alpha3 = symbols('alpha:4') a = alpha**2 - alpha*x**2 + alpha + x**3 - x*(alpha + 1) rep = (alpha, (1 + sqrt(5))/2 + alpha1*x + alpha2*x**2 + alpha3*x**3) s = (a/(x - alpha)).subs(*rep).series(x, 0, 1) assert simplify(collect(s, x)) == -sqrt(5)/2 - S(3)/2 + O(x) # issue 5917 assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1) assert _gcd_terms([2*x + 4]) == (2, x + 2, 1) eq = x/(x + 1/x) assert gcd_terms(eq, fraction=False) == eq eq = x/2/y + 1/x/y assert gcd_terms(eq, fraction=True, clear=True) == \ (x**2 + 2)/(2*x*y) assert gcd_terms(eq, fraction=True, clear=False) == \ (x**2/2 + 1)/(x*y) assert gcd_terms(eq, fraction=False, clear=True) == \ (x + 2/x)/(2*y) assert gcd_terms(eq, fraction=False, clear=False) == \ (x/2 + 1/x)/y
def test_make_args(): assert Add.make_args(x) == (x,) assert Mul.make_args(x) == (x,) assert Add.make_args(x*y*z) == (x*y*z,) assert Mul.make_args(x*y*z) == (x*y*z).args assert Add.make_args(x + y + z) == (x + y + z).args assert Mul.make_args(x + y + z) == (x + y + z,) assert Add.make_args((x + y)**z) == ((x + y)**z,) assert Mul.make_args((x + y)**z) == ((x + y)**z,)
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x
def test_make_args(): assert Add.make_args(x) == (x, ) assert Mul.make_args(x) == (x, ) assert Add.make_args(x * y * z) == (x * y * z, ) assert Mul.make_args(x * y * z) == (x * y * z).args assert Add.make_args(x + y + z) == (x + y + z).args assert Mul.make_args(x + y + z) == (x + y + z, ) assert Add.make_args((x + y)**z) == ((x + y)**z, ) assert Mul.make_args((x + y)**z) == ((x + y)**z, )
def test_gcd_terms(): f = 2 * (x + 1) * (x + 4) / (5 * x**2 + 5) + (2 * x + 2) * (x + 5) / ( x**2 + 1) / 5 + (2 * x + 2) * (x + 6) / (5 * x**2 + 5) assert _gcd_terms(f) == ((S(6) / 5) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6) / 5) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6) / 5) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6) / 5) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6)/5)*((1 + x)/(1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6)/5)*((1 + x)*(5 + x)/(1 + x**2)) assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False)
def _dict_from_basic_if_gens(ex, gens, **args): """Convert `ex` to a multinomial given a generators list. """ k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = {} for term in Add.make_args(ex): coeff, monom = [], [0] * k for factor in Mul.make_args(term): if factor.is_Number: coeff.append(factor) else: try: base, exp = _analyze_power(*factor.as_base_exp()) monom[indices[base]] = exp except KeyError: if not factor.has(*gens): coeff.append(factor) else: raise PolynomialError( "%s contains an element of the generators set" % factor) monom = tuple(monom) if monom in result: result[monom] += Mul(*coeff) else: result[monom] = Mul(*coeff) return result
def cancel_terms(sym, x_term, coef): if coef.is_Add: for arg_c in coef.args: sym = cancel_terms(sym, x_term, arg_c) else: terms = Add.make_args(sym) return Add.fromiter(t for t in terms if t != x_term*coef)
def z_to_coeffs(poly): """ Get a dictionary ``{delay: coeff, ...}`` from a z-transform expressed as a polynomial. The returned dictionary will contain :py:class:`int` ``delay`` values and SymPy expressions for the coefficients. """ # NB: Ideally you'd use SymPy's polynomial-related functions for this job # but, alas, SymPy doesn't support Laurent polynomials (where powers may be # negative). As a consequence, we do everything 'by hand'; using algebraic # operations rather than inspecting the SymPy data structures for reasons # of robustness. # Simplify the polynomial into a summation of multiples of powers of z. poly = collect(expand(poly), z) out = {} for arg in Add.make_args(poly): arg_no_z = arg.subs(z, 1) arg_z = arg / arg_no_z delay = -int((log(arg_z) / log(z)).expand(force=True)) out[delay] = arg_no_z # Add missing zeros terms (for completeness...) for delay in range(min(out), max(out)): out.setdefault(delay, 0) return out
def _dict_from_basic_if_gens(ex, gens, **args): """Convert `ex` to a multinomial given a generators list. """ k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = {} for term in Add.make_args(ex): coeff, monom = [], [0]*k for factor in Mul.make_args(term): if factor.is_Number: coeff.append(factor) else: try: base, exp = _analyze_power(*factor.as_Pow()) monom[indices[base]] = exp except KeyError: if not factor.has(*gens): coeff.append(factor) else: raise PolynomialError("%s contains an element of the generators set" % factor) monom = tuple(monom) if result.has_key(monom): result[monom] += Mul(*coeff) else: result[monom] = Mul(*coeff) return result
def _as_ordered_terms(self, expr, order=None): """A compatibility function for ordering terms in Add. """ order = order or self.order if order == 'old': return sorted(Add.make_args(expr), key=cmp_to_key(Basic._compare_pretty)) else: return expr.as_ordered_terms(order=order)
def _as_ordered_terms(self, expr, order=None): """A compatibility function for ordering terms in Add. """ order = order or self.order if order == 'old': return sorted(Add.make_args(expr), key=cmp_to_key(Basic._compare_pretty)) else: return expr.as_ordered_terms(order=order)
def test_gcd_terms(): f = 2 * (x + 1) * (x + 4) / (5 * x**2 + 5) + (2 * x + 2) * (x + 5) / ( x**2 + 1) / 5 + (2 * x + 2) * (x + 6) / (5 * x**2 + 5) assert _gcd_terms(f) == ((S(6) / 5) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == ((S(6) / 5) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert gcd_terms(f) == (S(6) / 5) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms(Add.make_args(f)) == (S(6) / 5) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms((2 * x + 2)**3 + (2 * x + 2)**2) == 4 * (x + 1)**2 * (2 * x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2 * x) == Mul(2, 1 + x, evaluate=False)
def latex_multline(expr, breaks, env="multline*", prefix=""): args = Add.make_args(expr) breaks = zip([0] + breaks, breaks + [len(args)]) def fmt_line(i, j): line = latex(Add(*args[i:j])) if i != 0 and latex(Add(*args[i:j]))[0] != '-': line = "+" + line return prefix + line return Latex("\\begin{{{0}}}\n{1}\n\\end{{{0}}}".format( env, "\\\\\n".join([fmt_line(i, j) for i, j in breaks])))
def _expandsums(sums): """ Helper function for _eval_expand_mul. sums must be a list of instances of Basic. """ L = len(sums) if L == 1: return sums[0].args terms = [] left = MatSymbolicMul._expandsums(sums[:L // 2]) right = MatSymbolicMul._expandsums(sums[L // 2:]) terms = [MatSymbolicMul(a, b) for a in left for b in right] added = MatSymbolicAdd(*terms) return Add.make_args(added) # it may have collapsed down to one term
def collect_by_nc(expr, evaluate=True): collected, disliked = defaultdict(list), S.Zero for arg in Add.make_args(expr): c, nc = arg.args_cnc() if nc: collected[Mul(*nc)].append(Mul(*c)) else: disliked += Mul(*c) collected = {k: Add(*v) for k, v in collected.items()} if disliked is not S.Zero: collected[S.One] = disliked if evaluate: return Add(*[key * val for key, val in collected.items()]) else: return collected
def sectionSeparate(formula, lmax): x = symbols('x', real=True) pos = set([ x - LM(f).args[0] for f in Add.make_args(formula) if len(f.atoms(StepFunc)) ]) pos.update([0, lmax]) pos = list(sorted(pos)) st = 0 formularr = [] # print("Line Segment Function") for en in pos[1:]: # print(formula.expand(lim=st, func=True)) formularr.append((formula.expand(lim=st, func=True), (x, st, en))) st = en return formularr
def collect_by_order(expr, evaluate=True): """ return dict d such that expr == Add(*[d[n] for n in d]) where Expr d[n] contains only terms with operator order n """ args = Add.make_args(expr) d = {} for arg in args: n = operator_order(arg) if n in d: d[n] += arg else: d[n] = arg d = {n: factor(collect_by_nc(arg)) for n, arg in d.items()} if evaluate: return Add(*[arg for arg in d.values()], evaluate=False) else: return d
def _make_converter(K): """Construct the converter to convert back to Expr""" # Precompute the effect of converting to sympy and expanding expressions # like (sqrt(2) + sqrt(3))**2. Asking Expr to do the expansion on every # conversion from K to Expr is slow. Here we compute the expansions for # each power of the generator and collect together the resulting algebraic # terms and the rational coefficients into a matrix. from sympy import Add, S gen = K.ext.as_expr() todom = K.dom.from_sympy # We'll let Expr compute the expansions. We won't make any presumptions # about what this results in except that it is QQ-linear in some terms # that we will call algebraics. The final result will be expressed in # terms of those. powers = [S.One, gen] for n in range(2, K.mod.degree()): powers.append((gen * powers[-1]).expand()) # Collect the rational coefficients and algebraic Expr that can # map the ANP coefficients into an expanded sympy expression terms = [ dict(t.as_coeff_Mul()[::-1] for t in Add.make_args(p)) for p in powers ] algebraics = set().union(*terms) matrix = [[todom(t.get(a, S.Zero)) for t in terms] for a in algebraics] # Create a function to do the conversion efficiently: def converter(a): """Convert a to Expr using converter""" from sympy import Add, Mul ai = a.rep[::-1] tosympy = K.dom.to_sympy coeffs_dom = [ sum(mij * aj for mij, aj in zip(mi, ai)) for mi in matrix ] coeffs_sympy = [tosympy(c) for c in coeffs_dom] res = Add(*(Mul(c, a) for c, a in zip(coeffs_sympy, algebraics))) return res return converter
def analyze(self, expr): """Rewrite an expression as sorted list of terms. """ gens, terms = set([]), [] for term in Add.make_args(expr): coeff, cpart, ncpart = [], {}, [] for factor in Mul.make_args(term): if not factor.is_commutative: ncpart.append(factor) else: if factor.is_Number: coeff.append(factor) else: base, exp = _analyze_power(*factor.as_base_exp()) cpart[base] = exp gens.add(base) terms.append((coeff, cpart, ncpart, term)) gens = sorted(gens, Basic._compare_pretty) k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = [] for coeff, cpart, ncpart, term in terms: monom = [0] * k for base, exp in cpart.iteritems(): monom[indices[base]] = exp result.append((coeff, monom, ncpart, term)) if self.order is None: return sorted(result, Basic._compare_pretty) else: return sorted(result, self._compare_terms)
def analyze(self, expr): """Rewrite an expression as sorted list of terms. """ gens, terms = set([]), [] for term in Add.make_args(expr): coeff, cpart, ncpart = [], {}, [] for factor in Mul.make_args(term): if not factor.is_commutative: ncpart.append(factor) else: if factor.is_Number: coeff.append(factor) else: base, exp = _analyze_power(*factor.as_base_exp()) cpart[base] = exp gens.add(base) terms.append((coeff, cpart, ncpart, term)) gens = sorted(gens, Basic._compare_pretty) k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = [] for coeff, cpart, ncpart, term in terms: monom = [0]*k for base, exp in cpart.iteritems(): monom[indices[base]] = exp result.append((coeff, monom, ncpart, term)) if self.order is None: return sorted(result, Basic._compare_pretty) else: return sorted(result, self._compare_terms)
def impluseFind(expr): x = symbols('x', real=True) imparr = [] for ex in Add.make_args(expr): mul = 1 x_impulse = x_moment = None for f in Mul.make_args(ex): if isinstance(f, StepFunc): if f.args[1] == -1: x_impulse = x - f.args[0] if f.args[1] == -2: x_moment = x - f.args[0] else: mul *= f if x_impulse != None: imparr.append((x_impulse, mul, -1)) elif x_moment != None: imparr.append((x_moment, mul, -2)) return imparr
def weightMul(expr, wei, lmax): x = symbols("x", real=True) wei = weightFill(wei, lmax) f = 0 for term in Add.make_args(expr): xfrm = 0 expterm = term for m in Mul.make_args(term): if isinstance(m, StepFunc): xfrm = x - m.args[0] expterm = term.expand(lim=lmax, func=True) func = m for w in wei: # outside range if w[2] <= xfrm: continue # partical inside range elif w[1] <= xfrm <= w[2]: f += buildStep(expterm * w[0], lmax, 0, xfrm, w[2]) # inside range else: f += buildStep(expterm * w[0], lmax, 0, w[1], w[2]) return f
def latex_align(data, env="align*", delim=None, breaks=None): # or set col_delim="&" for auto align if isinstance(data, list): delim = " " if delim is None else delim body = " \\\\\n".join( [delim.join([latex(col) for col in row]) for row in data]) if isinstance(data, Basic): args = Add.make_args(data) delim = "& " if delim is None else delim breaks = range(4, len(args) - 3, 4) if breaks is None else breaks breaks = zip([0] + list(breaks), list(breaks) + [len(args)]) def fmt_line(i, j): line = latex(Add(*args[i:j])) if i != 0 and latex(Add(*args[i:j]))[0] != '-': line = "+" + line return delim + line body = "\\\\\n".join([fmt_line(i, j) for i, j in breaks]) return Latex("\\begin{{{0}}}\n{1}\n\\end{{{0}}}".format(env, body))
def _dict_from_basic_no_gens(ex, **args): """Figure out generators and convert `ex` to a multinomial. """ domain = args.get('domain') if domain is not None: def _is_coeff(factor): return factor in domain else: extension = args.get('extension') if extension is True: def _is_coeff(factor): return ask(factor, 'algebraic') else: greedy = args.get('greedy', True) if greedy is True: def _is_coeff(factor): return False else: def _is_coeff(factor): return factor.is_number gens, terms = set([]), [] for term in Add.make_args(ex): coeff, elements = [], {} for factor in Mul.make_args(term): if factor.is_Number or _is_coeff(factor): coeff.append(factor) else: base, exp = _analyze_power(*factor.as_base_exp()) elements[base] = exp gens.add(base) terms.append((coeff, elements)) if not gens: raise GeneratorsNeeded("specify generators to give %s a meaning" % ex) gens = _sort_gens(gens, **args) k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = {} for coeff, term in terms: monom = [0] * k for base, exp in term.iteritems(): monom[indices[base]] = exp monom = tuple(monom) if monom in result: result[monom] += Mul(*coeff) else: result[monom] = Mul(*coeff) return result, tuple(gens)
def get_max_coef_list(sym, x_term): return [get_max_coef_mul(s, x_term) for s in Add.make_args(sym)]
def get_max_coef(sym, x_term): return Add.fromiter( get_max_coef_mul(s, x_term) for s in Add.make_args(sym) )
def test_identity_removal(): assert Add.make_args(x + 0) == (x,) assert Mul.make_args(x*1) == (x,)
def _dict_from_basic_no_gens(ex, **args): """Figure out generators and convert `ex` to a multinomial. """ domain = args.get('domain') if domain is not None: def _is_coeff(factor): return factor in domain else: extension = args.get('extension') if extension is True: def _is_coeff(factor): return ask(factor, 'algebraic') else: greedy = args.get('greedy', True) if greedy is True: def _is_coeff(factor): return False else: def _is_coeff(factor): return factor.is_number gens, terms = set([]), [] for term in Add.make_args(ex): coeff, elements = [], {} for factor in Mul.make_args(term): if factor.is_Number or _is_coeff(factor): coeff.append(factor) else: base, exp = _analyze_power(*factor.as_Pow()) elements[base] = exp gens.add(base) terms.append((coeff, elements)) if not gens: raise GeneratorsNeeded("specify generators to give %s a meaning" % ex) gens = _sort_gens(gens, **args) k, indices = len(gens), {} for i, g in enumerate(gens): indices[g] = i result = {} for coeff, term in terms: monom = [0]*k for base, exp in term.iteritems(): monom[indices[base]] = exp monom = tuple(monom) if result.has_key(monom): result[monom] += Mul(*coeff) else: result[monom] = Mul(*coeff) return result, tuple(gens)
def collect_const(expr, *vars, **kwargs): """ This is the very same code of sympy.simplify.radsimp.py collect_const, with modification: the original method used Mul._from_args and Add._from_args, which do not call a post-processor, hence I obtained the wrong result. Here, I use VecAdd, VecMul... """ if not expr.is_Add: return expr recurse = False Numbers = kwargs.get('Numbers', True) if not vars: recurse = True vars = set() for a in expr.args: for m in Mul.make_args(a): if m.is_number: vars.add(m) else: vars = sympify(vars) if not Numbers: vars = [v for v in vars if not v.is_Number] vars = list(ordered(vars)) for v in vars: terms = defaultdict(list) Fv = Factors(v) for m in Add.make_args(expr): f = Factors(m) q, r = f.div(Fv) if r.is_one: # only accept this as a true factor if # it didn't change an exponent from an Integer # to a non-Integer, e.g. 2/sqrt(2) -> sqrt(2) # -- we aren't looking for this sort of change fwas = f.factors.copy() fnow = q.factors if not any(k in fwas and fwas[k].is_Integer and not fnow[k].is_Integer for k in fnow): terms[v].append(q.as_expr()) continue terms[S.One].append(m) args = [] hit = False uneval = False for k in ordered(terms): v = terms[k] if k is S.One: args.extend(v) continue if len(v) > 1: v = Add(*v) hit = True if recurse and v != expr: vars.append(v) else: v = v[0] # be careful not to let uneval become True unless # it must be because it's going to be more expensive # to rebuild the expression as an unevaluated one if Numbers and k.is_Number and v.is_Add: # args.append(_keep_coeff(k, v, sign=True)) args.append(VecMul(*[k, v], evaluate=False)) uneval = True else: args.append(k * v) if hit: if uneval: # expr = Add(*args) expr = VecAdd(*args, evaluate=False) else: # expr = Add(*args) expr = VecAdd(*args) if not expr.is_Add: break return expr
def test_identity_removal(): assert Add.make_args(x + 0) == (x, ) assert Mul.make_args(x * 1) == (x, )