def _eval_simplify(self, ratio=1.7, measure=None, rational=False, inverse=False): from sympy.simplify.simplify import factor_sum, sum_combine from sympy.core.function import expand from sympy.core.mul import Mul # split the function into adds terms = Add.make_args(expand(self.function)) s_t = [] # Sum Terms o_t = [] # Other Terms for term in terms: if term.has(Sum): # if there is an embedded sum here # it is of the form x * (Sum(whatever)) # hence we make a Mul out of it, and simplify all interior sum terms subterms = Mul.make_args(expand(term)) out_terms = [] for subterm in subterms: # go through each term if isinstance(subterm, Sum): # if it's a sum, simplify it out_terms.append(subterm._eval_simplify()) else: # otherwise, add it as is out_terms.append(subterm) # turn it back into a Mul s_t.append(Mul(*out_terms)) else: o_t.append(term) # next try to combine any interior sums for further simplification result = Add(sum_combine(s_t), *o_t) return factor_sum(result, limits=self.limits)
def _eval_simplify(self, ratio=1.7, measure=None): from sympy.simplify.simplify import factor_sum, sum_combine from sympy.core.function import expand from sympy.core.mul import Mul # split the function into adds terms = Add.make_args(expand(self.function)) s_t = [] # Sum Terms o_t = [] # Other Terms for term in terms: if term.has(Sum): # if there is an embedded sum here # it is of the form x * (Sum(whatever)) # hence we make a Mul out of it, and simplify all interior sum terms subterms = Mul.make_args(expand(term)) out_terms = [] for subterm in subterms: # go through each term if isinstance(subterm, Sum): # if it's a sum, simplify it out_terms.append(subterm._eval_simplify()) else: # otherwise, add it as is out_terms.append(subterm) # turn it back into a Mul s_t.append(Mul(*out_terms)) else: o_t.append(term) # next try to combine any interior sums for further simplification result = Add(sum_combine(s_t), *o_t) return factor_sum(result, limits=self.limits)
def do(expr): from sympy.concrete.summations import Sum from sympy.simplify.simplify import factor_sum is_iterable = iterable(expr) if not isinstance(expr, Basic) or expr.is_Atom: if is_iterable: return type(expr)([do(i) for i in expr]) return expr if expr.is_Pow or expr.is_Function or \ is_iterable or not hasattr(expr, 'args_cnc'): args = expr.args newargs = tuple([do(i) for i in args]) if newargs == args: return expr return expr.func(*newargs) if isinstance(expr, Sum): return factor_sum(expr, radical=radical, clear=clear, fraction=fraction, sign=sign) cont, p = expr.as_content_primitive(radical=radical, clear=clear) if p.is_Add: list_args = [do(a) for a in Add.make_args(p)] # get a common negative (if there) which gcd_terms does not remove if all(a.as_coeff_Mul()[0].extract_multiplicatively(-1) is not None for a in list_args): cont = -cont list_args = [-a for a in list_args] # watch out for exp(-(x+2)) which gcd_terms will change to exp(-x-2) special = {} for i, a in enumerate(list_args): b, e = a.as_base_exp() if e.is_Mul and e != Mul(*e.args): list_args[i] = Dummy() special[list_args[i]] = a # rebuild p not worrying about the order which gcd_terms will fix p = Add._from_args(list_args) p = gcd_terms(p, isprimitive=True, clear=clear, fraction=fraction).xreplace(special) elif p.args: p = p.func(*[do(a) for a in p.args]) rv = _keep_coeff(cont, p, clear=clear, sign=sign) return rv
def do(expr): from sympy.concrete.summations import Sum from sympy.simplify.simplify import factor_sum is_iterable = iterable(expr) if not isinstance(expr, Basic) or expr.is_Atom: if is_iterable: return type(expr)([do(i) for i in expr]) return expr if expr.is_Pow or expr.is_Function or \ is_iterable or not hasattr(expr, 'args_cnc'): args = expr.args newargs = tuple([do(i) for i in args]) if newargs == args: return expr return expr.func(*newargs) if isinstance(expr, Sum): return factor_sum(expr, radical=radical, clear=clear, fraction=fraction, sign=sign) cont, p = expr.as_content_primitive(radical=radical, clear=clear) if p.is_Add: list_args = [do(a) for a in Add.make_args(p)] # get a common negative (if there) which gcd_terms does not remove if all(a.as_coeff_Mul()[0].extract_multiplicatively(-1) is not None for a in list_args): cont = -cont list_args = [-a for a in list_args] # watch out for exp(-(x+2)) which gcd_terms will change to exp(-x-2) special = {} for i, a in enumerate(list_args): b, e = a.as_base_exp() if e.is_Mul and e != Mul(*e.args): list_args[i] = Dummy() special[list_args[i]] = a # rebuild p not worrying about the order which gcd_terms will fix p = Add._from_args(list_args) p = gcd_terms(p, isprimitive=True, clear=clear, fraction=fraction).xreplace(special) elif p.args: p = p.func( *[do(a) for a in p.args]) rv = _keep_coeff(cont, p, clear=clear, sign=sign) return rv