(exprs, order='canonical')
return opt_subs
Find optimization opportunities in Adds, Muls, Pows and negative
    coefficient Muls

    Parameters
    ----------
    exprs : list of sympy expressions
        The expressions to optimize.
    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'.

    Returns
    -------
    opt_subs : dictionary of expression substitutions
        The expression substitutions which can be useful to optimize CSE.

    Examples
    --------
    >>> from sympy.simplify.cse_main import opt_cse
    >>> from sympy.abc import x
    >>> opt_subs = opt_cse([x**-2])
    >>> print(opt_subs)
    {x**(-2): 1/(x**2)}
Find optimization opportunities in Adds, Muls, Pows and negative
    coefficient Muls
Find optimization opportunities in Adds Muls Pows and negative coefficient Muls
def opt_cse(exprs, order='canonical'):
    """Find optimization opportunities in Adds, Muls, Pows and negative
    coefficient Muls

    Parameters
    ----------
    exprs : list of sympy expressions
        The expressions to optimize.
    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'.

    Returns
    -------
    opt_subs : dictionary of expression substitutions
        The expression substitutions which can be useful to optimize CSE.

    Examples
    --------
    >>> from sympy.simplify.cse_main import opt_cse
    >>> from sympy.abc import x
    >>> opt_subs = opt_cse([x**-2])
    >>> print(opt_subs)
    {x**(-2): 1/(x**2)}
    """
    from sympy.matrices import Matrix

    opt_subs = dict()

    adds = set()
    muls = set()

    seen_subexp = set()

    def _find_opts(expr):

        if expr.is_Atom or expr.is_Order:
            return

        if iterable(expr):
            list(map(_find_opts, expr))
            return

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

        list(map(_find_opts, expr.args))

        if _coeff_isneg(expr):
            neg_expr = -expr
            if not neg_expr.is_Atom:
                opt_subs[expr] = Mul(S.NegativeOne, neg_expr, evaluate=False)
                seen_subexp.add(neg_expr)
                expr = neg_expr

        if expr.is_Mul:
            muls.add(expr)

        elif expr.is_Add:
            adds.add(expr)

        elif expr.is_Pow:
            if _coeff_isneg(expr.exp):
                opt_subs[expr] = Pow(Pow(expr.base, -expr.exp), S.NegativeOne,
                                     evaluate=False)

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

    ## Process Adds and commutative Muls

    def _match_common_args(Func, funcs):
        if order != 'none':
            funcs = list(ordered(funcs))
        else:
            funcs = sorted(funcs, key=lambda x: len(x.args))

        func_args = [set(e.args) for e in funcs]
        for i in xrange(len(func_args)):
            for j in xrange(i + 1, len(func_args)):
                com_args = func_args[i].intersection(func_args[j])
                if len(com_args) > 1:
                    com_func = Func(*com_args)

                    # for all sets, replace the common symbols by the function
                    # over them, to allow recursive matches

                    diff_i = func_args[i].difference(com_args)
                    func_args[i] = diff_i | set([com_func])
                    if diff_i:
                        opt_subs[funcs[i]] = Func(Func(*diff_i), com_func,
                                                  evaluate=False)

                    diff_j = func_args[j].difference(com_args)
                    func_args[j] = diff_j | set([com_func])
                    opt_subs[funcs[j]] = Func(Func(*diff_j), com_func,
                                              evaluate=False)

                    for k in xrange(j + 1, len(func_args)):
                        if not com_args.difference(func_args[k]):
                            diff_k = func_args[k].difference(com_args)
                            func_args[k] = diff_k | set([com_func])
                            opt_subs[funcs[k]] = Func(Func(*diff_k), com_func,
                                                      evaluate=False)

    # split muls into commutative
    comutative_muls = set()
    for m in muls:
        c, nc = m.args_cnc(cset=True)
        if c:
            c_mul = Mul(*c)
            if nc:
                opt_subs[m] = Mul(c_mul, Mul(*nc), evaluate=False)
            if len(c) > 1:
                comutative_muls.add(c_mul)

    _match_common_args(Add, adds)
    _match_common_args(Mul, comutative_muls)

    return opt_subs
def opt_cse ( exprs , order = 'canonical' ) : from sympy . matrices import Matrix opt_subs = dict ( ) adds = set ( ) muls = set ( ) seen_subexp = set ( ) def _find_opts ( expr ) : if expr . is_Atom or expr . is_Order : return if iterable ( expr ) : list ( map ( _find_opts , expr ) ) return if expr in seen_subexp : return expr seen_subexp . add ( expr ) list ( map ( _find_opts , expr . args ) ) if _coeff_isneg ( expr ) : neg_expr = - expr if not neg_expr . is_Atom : opt_subs [ expr ] = Mul ( S . NegativeOne , neg_expr , evaluate = False ) seen_subexp . add ( neg_expr ) expr = neg_expr if expr . is_Mul : muls . add ( expr ) elif expr . is_Add : adds . add ( expr ) elif expr . is_Pow : if _coeff_isneg ( expr . exp ) : opt_subs [ expr ] = Pow ( Pow ( expr . base , - expr . exp ) , S . NegativeOne , evaluate = False ) for e in exprs : if isinstance ( e , Basic ) : _find_opts ( e ) ## Process Adds and commutative Muls def _match_common_args ( Func , funcs ) : if order != 'none' : funcs = list ( ordered ( funcs ) ) else : funcs = sorted ( funcs , key = lambda x : len ( x . args ) ) func_args = [ set ( e . args ) for e in funcs ] for i in xrange ( len ( func_args ) ) : for j in xrange ( i + 1 , len ( func_args ) ) : com_args = func_args [ i ] . intersection ( func_args [ j ] ) if len ( com_args ) > 1 : com_func = Func ( * com_args ) # for all sets, replace the common symbols by the function # over them, to allow recursive matches diff_i = func_args [ i ] . difference ( com_args ) func_args [ i ] = diff_i | set ( [ com_func ] ) if diff_i : opt_subs [ funcs [ i ] ] = Func ( Func ( * diff_i ) , com_func , evaluate = False ) diff_j = func_args [ j ] . difference ( com_args ) func_args [ j ] = diff_j | set ( [ com_func ] ) opt_subs [ funcs [ j ] ] = Func ( Func ( * diff_j ) , com_func , evaluate = False ) for k in xrange ( j + 1 , len ( func_args ) ) : if not com_args . difference ( func_args [ k ] ) : diff_k = func_args [ k ] . difference ( com_args ) func_args [ k ] = diff_k | set ( [ com_func ] ) opt_subs [ funcs [ k ] ] = Func ( Func ( * diff_k ) , com_func , evaluate = False ) # split muls into commutative comutative_muls = set ( ) for m in muls : c , nc = m . args_cnc ( cset = True ) if c : c_mul = Mul ( * c ) if nc : opt_subs [ m ] = Mul ( c_mul , Mul ( * nc ) , evaluate = False ) if len ( c ) > 1 : comutative_muls . add ( c_mul ) _match_common_args ( Add , adds ) _match_common_args ( Mul , comutative_muls ) return opt_subs