(exprs, symbols, opt_subs=None, order='canonical')
return replacements, reduced_exprs
Perform raw CSE on expression tree, taking opt_subs into account.

    Parameters
    ==========

    exprs : list of sympy expressions
        The expressions to reduce.
    symbols : infinite iterator yielding unique Symbols
        The symbols used to label the common subexpressions which are pulled
        out.
    opt_subs : dictionary of expression substitutions
        The expressions to be substituted before any CSE action is performed.
    order : string, 'none' or 'canonical'
        The order by which Mul and Add arguments are processed. For large
        expressions where speed is a concern, use the setting order='none'.
Perform raw CSE on expression tree, taking opt_subs into account.
Perform raw CSE on expression tree taking opt_subs into account .
def tree_cse(exprs, symbols, opt_subs=None, order='canonical'):
    """Perform raw CSE on expression tree, taking opt_subs into account.

    Parameters
    ==========

    exprs : list of sympy expressions
        The expressions to reduce.
    symbols : infinite iterator yielding unique Symbols
        The symbols used to label the common subexpressions which are pulled
        out.
    opt_subs : dictionary of expression substitutions
        The expressions to be substituted before any CSE action is performed.
    order : string, 'none' or 'canonical'
        The order by which Mul and Add arguments are processed. For large
        expressions where speed is a concern, use the setting order='none'.
    """
    from sympy.matrices import Matrix

    if opt_subs is None:
        opt_subs = dict()

    ## Find repeated sub-expressions

    to_eliminate = set()

    seen_subexp = set()

    def _find_repeated(expr):
        if expr.is_Atom or expr.is_Order:
            return

        if iterable(expr):
            args = expr

        else:
            if expr in seen_subexp:
                to_eliminate.add(expr)
                return

            seen_subexp.add(expr)

            if expr in opt_subs:
                expr = opt_subs[expr]

            args = expr.args

        list(map(_find_repeated, args))

    for e in exprs:
        if isinstance(e, Basic):
            _find_repeated(e)

    ## Rebuild tree

    replacements = []

    subs = dict()

    def _rebuild(expr):

        if expr.is_Atom:
            return expr

        if iterable(expr):
            new_args = [_rebuild(arg) for arg in expr]
            return expr.func(*new_args)

        if expr in subs:
            return subs[expr]

        orig_expr = expr
        if expr in opt_subs:
            expr = opt_subs[expr]

        # If enabled, parse Muls and Adds arguments by order to ensure
        # replacement order independent from hashes
        if order != 'none':
            if expr.is_Mul:
                c, nc = expr.args_cnc()
                args = list(ordered(c)) + nc
            elif expr.is_Add:
                args = list(ordered(expr.args))
            else:
                args = expr.args
        else:
            args = expr.args

        new_args = list(map(_rebuild, args))
        if new_args != args:
            new_expr = expr.func(*new_args)
        else:
            new_expr = expr

        if orig_expr in to_eliminate:
            try:
                sym = next(symbols)
            except StopIteration:
                raise ValueError("Symbols iterator ran out of symbols.")
            subs[orig_expr] = sym
            replacements.append((sym, new_expr))
            return sym

        else:
            return new_expr

    reduced_exprs = []
    for e in exprs:
        if isinstance(e, Basic):
            reduced_e = _rebuild(e)
        else:
            reduced_e = e
        reduced_exprs.append(reduced_e)

    return replacements, reduced_exprs
def tree_cse ( exprs , symbols , opt_subs = None , order = 'canonical' ) : from sympy . matrices import Matrix if opt_subs is None : opt_subs = dict ( ) ## Find repeated sub-expressions to_eliminate = set ( ) seen_subexp = set ( ) def _find_repeated ( expr ) : if expr . is_Atom or expr . is_Order : return if iterable ( expr ) : args = expr else : if expr in seen_subexp : to_eliminate . add ( expr ) return seen_subexp . add ( expr ) if expr in opt_subs : expr = opt_subs [ expr ] args = expr . args list ( map ( _find_repeated , args ) ) for e in exprs : if isinstance ( e , Basic ) : _find_repeated ( e ) ## Rebuild tree replacements = [ ] subs = dict ( ) def _rebuild ( expr ) : if expr . is_Atom : return expr if iterable ( expr ) : new_args = [ _rebuild ( arg ) for arg in expr ] return expr . func ( * new_args ) if expr in subs : return subs [ expr ] orig_expr = expr if expr in opt_subs : expr = opt_subs [ expr ] # If enabled, parse Muls and Adds arguments by order to ensure # replacement order independent from hashes if order != 'none' : if expr . is_Mul : c , nc = expr . args_cnc ( ) args = list ( ordered ( c ) ) + nc elif expr . is_Add : args = list ( ordered ( expr . args ) ) else : args = expr . args else : args = expr . args new_args = list ( map ( _rebuild , args ) ) if new_args != args : new_expr = expr . func ( * new_args ) else : new_expr = expr if orig_expr in to_eliminate : try : sym = next ( symbols ) except StopIteration : raise ValueError ( "Symbols iterator ran out of symbols." ) subs [ orig_expr ] = sym replacements . append ( ( sym , new_expr ) ) return sym else : return new_expr reduced_exprs = [ ] for e in exprs : if isinstance ( e , Basic ) : reduced_e = _rebuild ( e ) else : reduced_e = e reduced_exprs . append ( reduced_e ) return replacements , reduced_exprs