o
    ohnz                     @   sv  d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZmZmZ dd
lmZmZmZmZm Z m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, e,j-e,j.fedfgZ/dd Z0dd Z1dd Z2dd Z3dd Z4G dd dZ5G dd dZ6dd  Z7d,d"d#Z8d-d%d&Z9		'd.d(d)Z:d*d+ Z;dS )/z3 Tools for doing common subexpression elimination.
    )defaultdict)BasicMulAddPowsympify)Tuple
OrderedSet)factor_terms)S)ordered)symbolsSymbol)
MatrixBaseMatrixImmutableMatrixSparseMatrixImmutableSparseMatrix)
MatrixExprMatrixSymbolMatMulMatAddMatPowInverse)MatrixElement)RootOf)numbered_symbolssifttopological_sortiterable   )cse_optsNc                    sr   t   g }t D ]\}\}}t D ]\}\}}||jv r&|||f qq
 fddttt |fD S )a(  Sort replacements ``r`` so (k1, v1) appears before (k2, v2)
    if k2 is in v1's free symbols. This orders items in the
    way that cse returns its results (hence, in order to use the
    replacements in a substitution option it would make sense
    to reverse the order).

    Examples
    ========

    >>> from sympy.simplify.cse_main import reps_toposort
    >>> from sympy.abc import x, y
    >>> from sympy import Eq
    >>> for l, r in reps_toposort([(x, y + 1), (y, 2)]):
    ...     print(Eq(l, r))
    ...
    Eq(y, 2)
    Eq(x, y + 1)

    c                       g | ]} | qS  r#   .0irr#   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/simplify/cse_main.py
<listcomp>E       z!reps_toposort.<locals>.<listcomp>)r   	enumeratefree_symbolsappendr   rangelen)r(   Ec1k1v1c2k2v2r#   r'   r)   reps_toposort+   s   
"r8   c                 C   s8   t |dd }| dd |d D  } |d }t| |gS )a  Move expressions that are in the form (symbol, expr) out of the
    expressions and sort them into the replacements using the reps_toposort.

    Examples
    ========

    >>> from sympy.simplify.cse_main import cse_separate
    >>> from sympy.abc import x, y, z
    >>> from sympy import cos, exp, cse, Eq, symbols
    >>> x0, x1 = symbols('x:2')
    >>> eq = (x + 1 + exp((x + 1)/(y + 1)) + cos(y + 1))
    >>> cse([eq, Eq(x, z + 1), z - 2], postprocess=cse_separate) in [
    ... [[(x0, y + 1), (x, z + 1), (x1, x + 1)],
    ...  [x1 + exp(x1/x0) + cos(x0), z - 2]],
    ... [[(x1, y + 1), (x, z + 1), (x0, x + 1)],
    ...  [x0 + exp(x0/x1) + cos(x1), z - 2]]]
    ...
    True
    c                 S   s   | j o| jjS N)is_Equalitylhs	is_Symbol)wr#   r#   r)   <lambda>\   s    zcse_separate.<locals>.<lambda>c                 S      g | ]}|j qS r#   args)r%   r=   r#   r#   r)   r*   ]       z cse_separate.<locals>.<listcomp>TF)r   r8   )r(   edr#   r#   r)   cse_separateH   s   rE   c                    s8  | s|  fS t |  \tdt  }t|ttt fddtt D  t t fddd \ t 7 g }td }|dkr }|j@ }|ro|	d	d t|t
dD  |t| kr| |f n	|| |f |8 |d8 }|dksV|  ||fS )
a  
    Return tuples giving ``(a, b)`` where ``a`` is a symbol and ``b`` is
    either an expression or None. The value of None is used when a
    symbol is no longer needed for subsequent expressions.

    Use of such output can reduce the memory footprint of lambdified
    expressions that contain large, repeated subexpressions.

    Examples
    ========

    >>> from sympy import cse
    >>> from sympy.simplify.cse_main import cse_release_variables
    >>> from sympy.abc import x, y
    >>> eqs = [(x + y - 1)**2, x, x + y, (x + y)/(2*x + 1) + (x + y - 1)**2, (2*x + 1)**(x + y)]
    >>> defs, rvs = cse_release_variables(*cse(eqs))
    >>> for i in defs:
    ...   print(i)
    ...
    (x0, x + y)
    (x1, (x0 - 1)**2)
    (x2, 2*x + 1)
    (_3, x0/x2 + x1)
    (_4, x2**x0)
    (x2, None)
    (_0, x1)
    (x1, None)
    (_2, x0)
    (x0, None)
    (_1, x)
    >>> print(rvs)
    (_0, _1, _2, _3, _4)
    z_:%dc                    s   g | ]
} | | fqS r#   r#   r$   )rC   symsr#   r)   r*      s    z)cse_release_variables.<locals>.<listcomp>c                    s$   t fdd| d j @ D  S )Nc                 3   s"    | ]}  |  V  qd S r9   )index	count_opsr$   )psr#   r)   	<genexpr>   s    z:cse_release_variables.<locals>.<lambda>.<locals>.<genexpr>r   )sumr-   )x)in_userI   rJ   r#   r)   r>      s    
z'cse_release_variables.<locals>.<lambda>keyr    r   c                 S   s   g | ]}|d fqS r9   r#   r%   rJ   r#   r#   r)   r*      r+   )zipr   r0   listsetr/   sortedpopr-   extendstrr.   reverse)r(   rC   esymsrvr&   _pcr#   )rC   rN   rI   rJ   rF   r)   cse_release_variablesb   s:   "
r^   c                 C   s"   |D ]\}}|dur|| } q| S )a}   Preprocess an expression to optimize for common subexpression
    elimination.

    Parameters
    ==========

    expr : SymPy expression
        The target expression to optimize.
    optimizations : list of (callable, callable) pairs
        The (preprocessor, postprocessor) pairs.

    Returns
    =======

    expr : SymPy expression
        The transformed expression.
    Nr#   exproptimizationsprepostr#   r#   r)   preprocess_for_cse   s
   rd   c                 C   s&   t |D ]\}}|dur|| } q| S )a)  Postprocess an expression after common subexpression elimination to
    return the expression to canonical SymPy form.

    Parameters
    ==========

    expr : SymPy expression
        The target expression to transform.
    optimizations : list of (callable, callable) pairs, optional
        The (preprocessor, postprocessor) pairs.  The postprocessors will be
        applied in reversed order to undo the effects of the preprocessors
        correctly.

    Returns
    =======

    expr : SymPy expression
        The transformed expression.
    N)reversedr_   r#   r#   r)   postprocess_for_cse   s
   rf   c                   @   sL   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdddZ	dd Z
dS )FuncArgTrackerz}
    A class which manages a mapping from functions to arguments and an inverse
    mapping from arguments to functions.
    c                 C   sp   i | _ g | _g | _g | _t|D ]%\}}t }|jD ]}| |}|| | j| | q| j	| qd S r9   )
value_numbersvalue_number_to_valuearg_to_funcsetfunc_to_argsetr,   r	   rA   get_or_add_value_numberaddr.   )selffuncsfunc_ifuncfunc_argsetfunc_arg
arg_numberr#   r#   r)   __init__   s   


zFuncArgTracker.__init__c                    s    fddt |D S )zh
        Return the list of arguments in sorted order according to their value
        numbers.
        c                       g | ]} j | qS r#   )ri   )r%   argnrn   r#   r)   r*          z:FuncArgTracker.get_args_in_value_order.<locals>.<listcomp>)rU   )rn   argsetr#   rx   r)   get_args_in_value_order   s   z&FuncArgTracker.get_args_in_value_orderc                 C   s>   t | j}| j||}||kr| j| | jt  |S )zA
        Return the value number for the given argument.
        )r0   rh   
setdefaultri   r.   rj   r	   )rn   valuenvaluesvalue_numberr#   r#   r)   rl      s   
z&FuncArgTracker.get_or_add_value_numberc                 C   s$   | j | D ]
}| j| | qdS )zS
        Remove the function func_i from the argument to function mapping.
        N)rk   rj   remove)rn   rp   argr#   r#   r)   stop_arg_tracking  s   z FuncArgTracker.stop_arg_trackingr   c           
         s   t dd }|s
|S  fdd|D }t|td}|D ]}||u r"q|D ]}||kr2||  d7  < q$qt||gtd\}}	|D ]}|| dk rIq@||	v rU||  d7  < q@dd | D S )	a  Return a dict whose keys are function numbers. The entries of the dict are
        the number of arguments said function has in common with
        ``argset``. Entries have at least 2 items in common.  All keys have
        value at least ``min_func_i``.
        c                   S   s   dS )Nr   r#   r#   r#   r#   r)   r>     s    z:FuncArgTracker.get_common_arg_candidates.<locals>.<lambda>c                    rv   r#   )rj   r%   r   rx   r#   r)   r*     ry   z<FuncArgTracker.get_common_arg_candidates.<locals>.<listcomp>rO   r    c                 S   s   i | ]\}}|d kr||qS )   r#   )r%   kvr#   r#   r)   
<dictcomp>4  s    z<FuncArgTracker.get_common_arg_candidates.<locals>.<dictcomp>)r   maxr0   rU   items)
rn   rz   
min_func_i	count_mapfuncsetslargest_funcsetfuncsetrp   smaller_funcs_containerlarger_funcs_containerr#   rx   r)   get_common_arg_candidates  s4   z(FuncArgTracker.get_common_arg_candidatesNc                 C   sP   t |}tdd | jt| D }|dur||M }|D ]	}|| j| M }q|S )z
        Return a set of functions each of which whose argument list contains
        ``argset``, optionally filtered only to contain functions in
        ``restrict_to_funcset``.
        c                 s   s    | ]}|V  qd S r9   r#   )r%   fir#   r#   r)   rK   >  s    
z7FuncArgTracker.get_subset_candidates.<locals>.<genexpr>N)iterr	   rj   next)rn   rz   restrict_to_funcsetiargindicesr   r#   r#   r)   get_subset_candidates6  s   z$FuncArgTracker.get_subset_candidatesc                 C   sp   t |}| j| }|| D ]
}| j| | q|| D ]
}| j| | q| j|   | j| | dS )z@
        Update a function with a new set of arguments.
        N)r	   rk   rj   r   rm   clearupdate)rn   rp   
new_argsetnew_argsold_argsdeleted_arg	added_argr#   r#   r)   update_func_argsetI  s   
z!FuncArgTracker.update_func_argsetr   r9   )__name__
__module____qualname____doc__ru   r{   rl   r   r   r   r   r#   r#   r#   r)   rg      s    

(rg   c                   @   s4   e Zd Zdd Zdd Zdd Zedd ZeZd	S )
Unevaluatedc                 C   s   || _ || _d S r9   rq   rA   )rn   rq   rA   r#   r#   r)   ru   [  s   
zUnevaluated.__init__c                 C   s    d | jddd | jD S )NzUneval<{}>({})z, c                 s   s    | ]}t |V  qd S r9   )rX   r%   ar#   r#   r)   rK   a  s    z&Unevaluated.__str__.<locals>.<genexpr>)formatrq   joinrA   rx   r#   r#   r)   __str___  s   zUnevaluated.__str__c                 C   s   | j | jddiS )NevaluateFr   rx   r#   r#   r)   as_unevaluated_basicc  s   z Unevaluated.as_unevaluated_basicc                 C   s   t  jdd | jD  S )Nc                 S   r?   r#   )r-   r   r#   r#   r)   r*   h  rB   z,Unevaluated.free_symbols.<locals>.<listcomp>)rT   unionrA   rx   r#   r#   r)   r-   f  s   zUnevaluated.free_symbolsN)	r   r   r   ru   r   r   propertyr-   __repr__r#   r#   r#   r)   r   Y  s    
r   c                    s  t |dd d}t|}t }tt|D ]}|j|j| |d d tt    fddd}|r|jdd}|j| 	|j| }t|dkrKq1|j| 
|}	|	rst| ||}
||
}|||	t|gB  || n||| }|j| 
|}|||t|gB  || |||D ]}|j| 
|}|||t|gB  || q|s3||v rt| ||j| ||| < || qd	S )
aw  
    Recognize and extract common subexpressions of function arguments within a
    set of function calls. For instance, for the following function calls::

        x + z + y
        sin(x + y)

    this will extract a common subexpression of `x + y`::

        w = x + y
        w + z
        sin(w)

    The function we work with is assumed to be associative and commutative.

    Parameters
    ==========

    func_class: class
        The function class (e.g. Add, Mul)
    funcs: list of functions
        A list of function calls.
    opt_subs: dict
        A dictionary of substitutions which this function may update.
    c                 S   s
   t | jS r9   )r0   rA   )fr#   r#   r)   r>     s   
 z#match_common_args.<locals>.<lambda>rO   r    )r   c                    s    |  | fS r9   r#   )r   common_arg_candidates_countsr#   r)   r>     s    F)lastN)rU   rg   r	   r/   r0   r   rk   keysrV   intersection
differencer   r{   rl   r   rm   r   r   )
func_classro   opt_subsarg_trackerchangedr&   common_arg_candidatesjcom_argsdiff_icom_funccom_func_numberdiff_jr   diff_kr#   r   r)   match_common_argsm  sV   





+r   	canonicalc           
         sP  i t  t  t t  fdd | D ]}t|ttfr( | qfddD }tt|fD ]}|jd |jd |< q:t  }D ]I}|j	dd\}}|r|j
| }|r|dkrm|j
| }	nt|tr|j
|g|R d	di}	n|j
||j
| dd
}	|	|< t|dkr|| qPtt tt| S )a=  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])
    >>> k, v = list(opt_subs.keys())[0], list(opt_subs.values())[0]
    >>> print((k, v.as_unevaluated_basic()))
    (x**(-2), 1/(x**2))
    c                    s  t | ttfs	d S | js| jrd S t| rtt |  d S | v r$| S |  tt | j	 t | t
sa|  rat | trJtdd | j	D  }n|  }|jsatttj|f| < | |} t | ttfr}t| j	dkrv|  d S |  d S t | ttfrt| j	dkr|  d S |  d S t | trd S t | ttfr| j| j}}| rttt|| df| < d S d S d S )Nc                 s   s    | ]}| V  qd S r9   r#   r$   r#   r#   r)   rK     s    z.opt_cse.<locals>._find_opts.<locals>.<genexpr>r    )
isinstancer   r   is_Atomis_Orderr   rS   maprm   rA   r   could_extract_minus_signr   r   r   NegativeOner   r0   r   r   r   r   baseexp)r`   neg_exprr   r   
_find_optsaddscollapsible_subexpmulsr   seen_subexpr#   r)   r     sF   



zopt_cse.<locals>._find_optsc                    s(   g | ]}|j d   v r||j d  fqS r   r@   rQ   )r   r#   r)   r*   *  s    zopt_cse.<locals>.<listcomp>r   F)csetr    r   )r   )r	   rT   r   r   r   re   r   getrA   args_cncrq   r   r0   rm   r   r   r   )
exprsorderrC   edgescommutative_mulsmr]   ncc_mulnew_objr#   r   r)   opt_cse  s>   5


r   r#   c                    s   du ri t  
t  t   
fdd | D ]}t|tr' | qfdd	D 	g i 	
fddg }| D ]}t|trQ|}n|}|| qE|fS )a  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'.
    ignore : iterable of Symbols
        Substitutions containing any Symbol from ``ignore`` will be ignored.
    Nc                    s   t | ttfs	d S t | trd S t | tr-| js"| js"t | ttfr-| jr+	| j
 d S t| r4| }n'| v rKD ]	}|| jv rC nq:	|  d S 	|  | v rX|  } | j}tt | d S r9   )r   r   r   r   r   r   r   r   r<   rm   namer   r-   rA   rS   r   )r`   rA   ign)_find_repeatedexcluded_symbolsignorer   r   to_eliminater#   r)   r   d  s8   




z tree_cse.<locals>._find_repeatedc                 3   s    | ]
}|j  vr|V  qd S r9   )r   )r%   _)r   r#   r)   rK     s    ztree_cse.<locals>.<genexpr>c                    sl  t | ttfs	| S | js| S t| r! fdd| jD }| j| S | v r)|  S | }| v r3|  } dkrht | ttfrU|  \}}|dgkrL|}nt	t
|| }nt | ttfrdt	t
| j}n| j}n| j}t	t |}t | ts{||kr| j| }n| }|v rzt}W n ty   tdw t |trt|j|j|j}||< ||f |S |S )Nc                    s   g | ]} |qS r#   r#   r   )_rebuildr#   r)   r*     r+   z.tree_cse.<locals>._rebuild.<locals>.<listcomp>noner    z$Symbols iterator ran out of symbols.)r   r   r   rA   r   rq   r   r   r   rS   r   r   r   r   r   StopIteration
ValueErrorr   r   r   rowscolsr.   )r`   r   	orig_exprr]   r   rA   new_exprsym)r   r   r   replacementssubsr   r   r#   r)   r     sP   



ztree_cse.<locals>._rebuild)rT   r   r   r.   )r   r   r   r   r   rC   reduced_exprs	reduced_er#   )r   r   r   r   r   r   r   r   r   r   r   r)   tree_cseG  s*   $
9

r   Tc                    s  |st | | |||dS t| ttfrt| } t| ttfr!| g} | }g }| D ]+}	t|	ttfr:|	t
|	   q't|	ttfrM|	t
|	    q'|	|	 q'|} ~ du r]g  n dkrct  fdd| D }
|du rvttd}nt|}t|
|}t|
||||\}}
|} t|D ]\}\}}t| }||f||< q fdd|
D }
t| D ]N\}}	t|	ttfrt|	j|	j|
| |
|< t|	tr|
|  |
|< qt|	ttfrt|	j|	ji }|
| D ]\}}|||< qt|	tr| }||
|< q|du r||
fS |||
S )as   Perform common subexpression elimination on an expression.

    Parameters
    ==========

    exprs : list of SymPy expressions, or a single SymPy expression
        The expressions to reduce.
    symbols : infinite iterator yielding unique Symbols
        The symbols used to label the common subexpressions which are pulled
        out. The ``numbered_symbols`` generator is useful. The default is a
        stream of symbols of the form "x0", "x1", etc. This must be an
        infinite iterator.
    optimizations : list of (callable, callable) pairs
        The (preprocessor, postprocessor) pairs of external optimization
        functions. Optionally 'basic' can be passed for a set of predefined
        basic optimizations. Such 'basic' optimizations were used by default
        in old implementation, however they can be really slow on larger
        expressions. Now, no pre or post optimizations are made by default.
    postprocess : a function which accepts the two return values of cse and
        returns the desired form of output from cse, e.g. if you want the
        replacements reversed the function might be the following lambda:
        lambda r, e: return reversed(r), e
    order : string, 'none' or 'canonical'
        The order by which Mul and Add arguments are processed. If set to
        'canonical', arguments will be canonically ordered. If set to 'none',
        ordering will be faster but dependent on expressions hashes, thus
        machine dependent and variable. For large expressions where speed is a
        concern, use the setting order='none'.
    ignore : iterable of Symbols
        Substitutions containing any Symbol from ``ignore`` will be ignored.
    list : bool, (default True)
        Returns expression in list or else with same type as input (when False).

    Returns
    =======

    replacements : list of (Symbol, expression) pairs
        All of the common subexpressions that were replaced. Subexpressions
        earlier in this list might show up in subexpressions later in this
        list.
    reduced_exprs : list of SymPy expressions
        The reduced expressions with all of the replacements above.

    Examples
    ========

    >>> from sympy import cse, SparseMatrix
    >>> from sympy.abc import x, y, z, w
    >>> cse(((w + x + y + z)*(w + y + z))/(w + x)**3)
    ([(x0, y + z), (x1, w + x)], [(w + x0)*(x0 + x1)/x1**3])


    List of expressions with recursive substitutions:

    >>> m = SparseMatrix([x + y, x + y + z])
    >>> cse([(x+y)**2, x + y + z, y + z, x + z + y, m])
    ([(x0, x + y), (x1, x0 + z)], [x0**2, x1, y + z, x1, Matrix([
    [x0],
    [x1]])])

    Note: the type and mutability of input matrices is retained.

    >>> isinstance(_[1][-1], SparseMatrix)
    True

    The user may disallow substitutions containing certain symbols:

    >>> cse([y**2*(x + 1), 3*y**2*(x + 1)], ignore=(y,))
    ([(x0, x + 1)], [x0*y**2, 3*x0*y**2])

    The default return value for the reduced expression(s) is a list, even if there is only
    one expression. The `list` flag preserves the type of the input in the output:

    >>> cse(x)
    ([], [x])
    >>> cse(x, list=False)
    ([], x)
    )r   ra   postprocessr   r   Nbasicc                       g | ]}t | qS r#   )rd   r%   rC   ra   r#   r)   r*   F  ry   zcse.<locals>.<listcomp>)clsc                    r   r#   )rf   r   r   r#   r)   r*   [  s    )_cse_homogeneousr   intfloatr   r   r   r   r   r.   r   flatr   r   todokr   basic_optimizationsr   r   r   r   r   r,   rf   r   r   as_immutable)r   r   ra   r   r   r   rS   copytemprC   r   r   r   r&   r   subtreer   r   r   r#   r   r)   cse  sn   P







r  c                    s   t  trtt fi |\}}|t|fS t  tttfr1t fi |\}}|t	 |fS t  t
rXt  }t fdd|D fi |\}}t
t||}||fS zt fi |\}\}W ||fS  tyu   g  f Y S w )aM  
    Same as ``cse`` but the ``reduced_exprs`` are returned
    with the same type as ``exprs`` or a sympified version of the same.

    Parameters
    ==========

    exprs : an Expr, iterable of Expr or dictionary with Expr values
        the expressions in which repeated subexpressions will be identified
    kwargs : additional arguments for the ``cse`` function

    Returns
    =======

    replacements : list of (Symbol, expression) pairs
        All of the common subexpressions that were replaced. Subexpressions
        earlier in this list might show up in subexpressions later in this
        list.
    reduced_exprs : list of SymPy expressions
        The reduced expressions with all of the replacements above.

    Examples
    ========

    >>> from sympy.simplify.cse_main import cse
    >>> from sympy import cos, Tuple, Matrix
    >>> from sympy.abc import x
    >>> output = lambda x: type(cse(x, list=False)[1])
    >>> output(1)
    <class 'sympy.core.numbers.One'>
    >>> output('cos(x)')
    <class 'str'>
    >>> output(cos(x))
    cos
    >>> output(Tuple(1, x))
    <class 'sympy.core.containers.Tuple'>
    >>> output(Matrix([[1,0], [0,1]]))
    <class 'sympy.matrices.dense.MutableDenseMatrix'>
    >>> output([1, x])
    <class 'list'>
    >>> output((1, x))
    <class 'tuple'>
    >>> output({1, x})
    <class 'set'>
    c                    r"   r#   r#   )r%   r   r   r#   r)   r*     r+   z$_cse_homogeneous.<locals>.<listcomp>)r   rX   r   r   reprrS   tuplerT   r  typedictr   rR   	TypeError)r   kwargsr   r   r   valuesr#   r	  r)   r   r  s*   
.

"r   )r   )Nr   r#   )NNNr   r#   T)<r   collectionsr   
sympy.corer   r   r   r   r   sympy.core.containersr   r	   sympy.core.exprtoolsr
   sympy.core.singletonr   sympy.core.sortingr   sympy.core.symbolr   r   sympy.matricesr   r   r   r   r   sympy.matrices.expressionsr   r   r   r   r   r   "sympy.matrices.expressions.matexprr   sympy.polys.rootoftoolsr   sympy.utilities.iterablesr   r   r   r    r!   sub_presub_postr  r8   rE   r^   rd   rf   rg   r   r   r   r   r  r   r#   r#   r#   r)   <module>   sB     
F
^
| 
 