U
    ZÊ¹j–<  ã                   @   sÌ  d dl mZmZ d dlmZ d dlmZmZmZ d dl	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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  d dl!m"Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m*Z* ddl+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1 G dd„ de'eƒZ2e
 3ee2fe2¡ dd„ Z4dd„ Z5dd„ Z6dd„ Z7dd„ Z8d d!„ Z9d"d#„ Z:d$d%„ Z;d&d'„ Z<e<e5e7e;e9eed(d)„ ƒe6e8ee:fZ=eee2ee=Ž iƒƒZ>d*d+„ Z?d,d-„ Z@e@ed< d.S )/é    )ÚaskÚQ)Úhandlers_dict)ÚBasicÚsympifyÚS)ÚmulÚMul)ÚNumberÚInteger©ÚDummy©Úadjoint)Úrm_idÚunpackÚtypedÚflattenÚexhaustÚdo_oneÚnew)ÚNonInvertibleMatrixError)Ú
MatrixBase)Úsympy_deprecation_warning)Úvalidate_matmul_integeré   )ÚInverse)Ú
MatrixExpr)ÚMatPow©Ú	transpose)ÚPermutationMatrix)Ú
ZeroMatrixÚIdentityÚGenericIdentityÚ	OneMatrixc                       s°   e Zd ZdZdZeƒ Zddddœdd„Zedd	„ ƒZ	e
d
d„ ƒZd$dd„Zdd„ Zdd„ Z‡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd%d d!„Zd"d#„ Z‡  ZS )&ÚMatMula  
    A product of matrix expressions

    Examples
    ========

    >>> from sympy import MatMul, MatrixSymbol
    >>> A = MatrixSymbol('A', 5, 4)
    >>> B = MatrixSymbol('B', 4, 3)
    >>> C = MatrixSymbol('C', 3, 6)
    >>> MatMul(A, B, C)
    A*B*C
    TFN)ÚevaluateÚcheckÚ_sympifyc                   sŽ   |s
ˆ j S tt‡ fdd„|ƒƒ}|r2ttt|ƒƒ}tjˆ f|žŽ }| ¡ \}}|d k	rdtdddd� |dk	rtt	|Ž  |s||S |rŠˆ  
|¡S |S )Nc                    s
   ˆ j | kS ©N)Úidentity)Úi©Úcls© ú`/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/matrices/expressions/matmul.pyÚ<lambda>0   ó    z MatMul.__new__.<locals>.<lambda>zaPassing check to MatMul is deprecated and the check argument will be removed in a future version.z1.11z,remove-check-argument-from-matrix-operations)Zdeprecated_since_versionZactive_deprecations_targetF)r+   ÚlistÚfilterÚmapr   r   Ú__new__Úas_coeff_matricesr   ÚvalidateÚ	_evaluate)r.   r'   r(   r)   ÚargsÚobjÚfactorÚmatricesr/   r-   r0   r6   *   s(    ý
zMatMul.__new__c                 C   s   t |ƒS r*   )Úcanonicalize)r.   Úexprr/   r/   r0   r9   J   s    zMatMul._evaluatec                 C   s$   dd„ | j D ƒ}|d j|d jfS )Nc                 S   s   g | ]}|j r|‘qS r/   ©Ú	is_Matrix©Ú.0Úargr/   r/   r0   Ú
<listcomp>P   s      z MatMul.shape.<locals>.<listcomp>r   éÿÿÿÿ)r:   ÚrowsÚcols)Úselfr=   r/   r/   r0   ÚshapeN   s    zMatMul.shapec                    sn  ddl m} ddlm‰  |  ¡ \}}t|ƒdkrD||d ||f  S d gt|ƒd  ‰d gt|ƒd  }|ˆd< |ˆd< dd„ }	| d|	ƒ ¡‰tdt|ƒƒD ]}tˆƒˆ|< qœt	|d d… ƒD ]\}}
|
j
d d ||< q¾‡‡fd	d
„t	|ƒD ƒ}t |¡}t‡ fdd„|D ƒƒ�rd}|||ftˆdd… dgt|ƒ |ƒžŽ  }tdd„ |D ƒƒ�s\d}|�rj| ¡ S |S )Nr   )ÚSum©ÚImmutableMatrixr   rF   c                  s   s    d} t d|  ƒV  | d7 } qd S )Nr   zi_%ir   )Úcounterr/   r/   r0   Úfb   s    zMatMul._entry.<locals>.fÚdummy_generatorc                    s,   g | ]$\}}|j ˆ| ˆ|d   ˆ d�‘qS )r   )rP   )Ú_entry©rC   r,   rD   )rP   Úindicesr/   r0   rE   o   s     z!MatMul._entry.<locals>.<listcomp>c                 3   s   | ]}|  ˆ ¡V  qd S r*   ©Úhas©rC   ÚvrL   r/   r0   Ú	<genexpr>q   s     z MatMul._entry.<locals>.<genexpr>Tc                 s   s   | ]}t |ttfƒV  qd S r*   )Ú
isinstancer   ÚintrV   r/   r/   r0   rX   y   s     F)Zsympy.concrete.summationsrK   Zsympy.matrices.immutablerM   r7   ÚlenÚgetÚrangeÚnextÚ	enumeraterJ   r	   ÚfromiterÚanyÚzipÚdoit)rI   r,   ÚjÚexpandÚkwargsrK   Úcoeffr=   Z
ind_rangesrO   rD   Zexpr_in_sumÚresultr/   )rM   rP   rS   r0   rQ   S   s6    
ÿþzMatMul._entryc                 C   sB   dd„ | j D ƒ}dd„ | j D ƒ}t|Ž }|jdkr:tdƒ‚||fS )Nc                 S   s   g | ]}|j s|‘qS r/   r@   ©rC   Úxr/   r/   r0   rE   ~   s      z,MatMul.as_coeff_matrices.<locals>.<listcomp>c                 S   s   g | ]}|j r|‘qS r/   r@   ri   r/   r/   r0   rE      s      Fz3noncommutative scalars in MatMul are not supported.)r:   r	   Úis_commutativeÚNotImplementedError)rI   Zscalarsr=   rg   r/   r/   r0   r7   }   s    
zMatMul.as_coeff_matricesc                 C   s   |   ¡ \}}|t|Ž fS r*   )r7   r&   ©rI   rg   r=   r/   r/   r0   Úas_coeff_mmul†   s    zMatMul.as_coeff_mmulc                    s   t t| ƒjf |Ž}|  |¡S r*   )Úsuperr&   re   r9   )rI   rf   Úexpanded©Ú	__class__r/   r0   re   Š   s    zMatMul.expandc                 C   s2   |   ¡ \}}t|fdd„ |ddd… D ƒžŽ  ¡ S )a¨  Transposition of matrix multiplication.

        Notes
        =====

        The following rules are applied.

        Transposition for matrix multiplied with another matrix:
        `\left(A B\right)^{T} = B^{T} A^{T}`

        Transposition for matrix multiplied with scalar:
        `\left(c A\right)^{T} = c A^{T}`

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Transpose
        c                 S   s   g | ]}t |ƒ‘qS r/   r   rB   r/   r/   r0   rE   £   s     z*MatMul._eval_transpose.<locals>.<listcomp>NrF   )r7   r&   rc   rm   r/   r/   r0   Ú_eval_transposeŽ   s    ÿÿzMatMul._eval_transposec                 C   s"   t dd„ | jd d d… D ƒŽ  ¡ S )Nc                 S   s   g | ]}t |ƒ‘qS r/   r   rB   r/   r/   r0   rE   ¦   s     z(MatMul._eval_adjoint.<locals>.<listcomp>rF   )r&   r:   rc   ©rI   r/   r/   r0   Ú_eval_adjoint¥   s    zMatMul._eval_adjointc                 C   s4   |   ¡ \}}|dkr0ddlm} ||| ¡ ƒ S d S )Nr   )Útrace)rn   rv   rc   )rI   r<   Úmmulrv   r/   r/   r0   Ú_eval_trace¨   s    zMatMul._eval_tracec                 C   s<   ddl m} |  ¡ \}}t|Ž }|| j ttt||ƒƒŽ  S )Nr   )ÚDeterminant)Z&sympy.matrices.expressions.determinantry   r7   Úonly_squaresrG   r	   r3   r5   )rI   ry   r<   r=   Zsquare_matricesr/   r/   r0   Ú_eval_determinant®   s    zMatMul._eval_determinantc                 C   s>   t dd„ | jD ƒƒr6tdd„ | jd d d… D ƒŽ  ¡ S t| ƒS )Nc                 s   s   | ]}t |tƒr|jV  qd S r*   )rY   r   Ú	is_squarerB   r/   r/   r0   rX   µ   s     
 z'MatMul._eval_inverse.<locals>.<genexpr>c                 s   s(   | ] }t |tƒr| ¡ n|d  V  qdS )rF   N)rY   r   ÚinverserB   r/   r/   r0   rX   ¶   s   ÿrF   )Úallr:   r&   rc   r   rt   r/   r/   r0   Ú_eval_inverse´   s
    þzMatMul._eval_inversec                    s@   ˆ   dd¡}|r*t‡ fdd„| jD ƒƒ}n| j}tt|Ž ƒ}|S )NÚdeepTc                 3   s   | ]}|j f ˆ ŽV  qd S r*   )rc   rB   ©Úhintsr/   r0   rX   À   s     zMatMul.doit.<locals>.<genexpr>)r\   Útupler:   r>   r&   )rI   r‚   r€   r:   r?   r/   r�   r0   rc   ½   s    zMatMul.doitc                    sj   dd„ ˆ j D ƒ}dd„ ˆ j D ƒ}|rbt|ƒ}t|ƒ}|rb|rbt|ƒ|krbtd‡ fdd„|D ƒ ƒ‚||gS )Nc                 S   s   g | ]}|j r|‘qS r/   ©rk   ri   r/   r/   r0   rE   Ê   s      z#MatMul.args_cnc.<locals>.<listcomp>c                 S   s   g | ]}|j s|‘qS r/   r„   ri   r/   r/   r0   rE   Ë   s      z"repeated commutative arguments: %sc                    s$   g | ]}t ˆ jƒ |¡d kr|‘qS ©r   )r3   r:   Úcount)rC   Úcirt   r/   r0   rE   Ñ   s      )r:   r[   ÚsetÚ
ValueError)rI   ZcsetÚwarnrf   Zcoeff_cZcoeff_ncZclenr/   rt   r0   Úargs_cncÉ   s    ÿzMatMul.args_cncc                    sÜ   ddl m‰  ‡fdd„t| jƒD ƒ}g }|D ]ª}| jd |… }| j|d d … }|r`t |¡}nt| jd ƒ}|r�t ‡ fdd„t|ƒD ƒ¡}nt| jd ƒ}| j|  	ˆ¡}	|	D ]"}
|
 
|¡ |
 |¡ | |
¡ q²q,|S )Nr   ©Ú	Transposec                    s   g | ]\}}|  ˆ ¡r|‘qS r/   rT   rR   ©rj   r/   r0   rE   Ö   s     
 z8MatMul._eval_derivative_matrix_lines.<locals>.<listcomp>c                    s"   g | ]}|j rˆ |ƒ ¡ n|‘qS r/   )rA   rc   )rC   r,   rŒ   r/   r0   rE   á   s     r   )r    r�   r_   r:   r&   r`   r#   rJ   ÚreversedÚ_eval_derivative_matrix_linesZappend_firstZappend_secondÚappend)rI   rj   Z
with_x_indÚlinesÚindZ	left_argsZ
right_argsZ	right_matZleft_revÚdr,   r/   )r�   rj   r0   r�   Ô   s$    

z$MatMul._eval_derivative_matrix_lines)T)FT)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Z	is_MatMulr$   r+   r6   Úclassmethodr9   ÚpropertyrJ   rQ   r7   rn   re   rs   ru   rx   r{   r   rc   r‹   r�   Ú__classcell__r/   r/   rq   r0   r&      s(    


*		
r&   c                  G   s&   | d dkr| dd … } t tf| žŽ S )Nr   r   )r   r&   ©r:   r/   r/   r0   Únewmulñ   s    r�   c                 C   s>   t dd„ | jD ƒƒr:dd„ | jD ƒ}t|d j|d jƒS | S )Nc                 s   s    | ]}|j p|jo|jV  qd S r*   )Úis_zerorA   Zis_ZeroMatrixrB   r/   r/   r0   rX   ÷   s   ÿzany_zeros.<locals>.<genexpr>c                 S   s   g | ]}|j r|‘qS r/   r@   rB   r/   r/   r0   rE   ù   s      zany_zeros.<locals>.<listcomp>r   rF   )ra   r:   r"   rG   rH   )r   r=   r/   r/   r0   Ú	any_zerosö   s    ÿrŸ   c                 C   s€   t dd„ | jD ƒƒs| S g }| jd }| jdd… D ]8}t|ttfƒr^t|ttfƒr^|| }q4| |¡ |}q4| |¡ t|Ž S )a˜   Merge explicit MatrixBase arguments

    >>> from sympy import MatrixSymbol, Matrix, MatMul, pprint
    >>> from sympy.matrices.expressions.matmul import merge_explicit
    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = Matrix([[1, 1], [1, 1]])
    >>> C = Matrix([[1, 2], [3, 4]])
    >>> X = MatMul(A, B, C)
    >>> pprint(X)
      [1  1] [1  2]
    A*[    ]*[    ]
      [1  1] [3  4]
    >>> pprint(merge_explicit(X))
      [4  6]
    A*[    ]
      [4  6]

    >>> X = MatMul(B, A, C)
    >>> pprint(X)
    [1  1]   [1  2]
    [    ]*A*[    ]
    [1  1]   [3  4]
    >>> pprint(merge_explicit(X))
    [1  1]   [1  2]
    [    ]*A*[    ]
    [1  1]   [3  4]
    c                 s   s   | ]}t |tƒV  qd S r*   )rY   r   rB   r/   r/   r0   rX     s     z!merge_explicit.<locals>.<genexpr>r   r   N)ra   r:   rY   r   r
   r‘   r&   )ÚmatmulÚnewargsÚlastrD   r/   r/   r0   Úmerge_explicitý   s    



r£   c                 C   s<   |   ¡ \}}tdd„ ƒ|ƒ}||kr4t|f|jžŽ S | S dS )zñ Remove Identities from a MatMul

    This is a modified version of sympy.strategies.rm_id.
    This is necesssary because MatMul may contain both MatrixExprs and Exprs
    as args.

    See Also
    ========

    sympy.strategies.rm_id
    c                 S   s
   | j dkS )NT)Zis_IdentityrŽ   r/   r/   r0   r1   6  r2   zremove_ids.<locals>.<lambda>N)rn   r   r�   r:   )r   r<   rw   rh   r/   r/   r0   Ú
remove_ids'  s
    r¤   c                 C   s&   |   ¡ \}}|dkr"t|f|žŽ S | S ©Nr   )r7   r�   )r   r<   r=   r/   r/   r0   Úfactor_in_front<  s    r¦   c              	   C   s(  |   ¡ \}}|d g}tdt|ƒƒD �]ò}|d }|| }t|tƒr–t|jtƒr–|jj}t|ƒ}t|ƒ|| d… kr–|d| … t	|j
d ƒg }q$t|tƒ�rt|jtƒ�r|jj}	t|	ƒ}t|	ƒ|||| … k�rt	|j
d ƒ}
|
|d< t||| ƒD ]}|
||< qþq$|jdk�s&|jdk�r2| |¡ q$t|tƒ�rJ|j\}}n|tj }}t|tƒ�rn|j\}}n|tj }}||k�r¦|| }t||ƒjdd�|d< q$nht|tƒ�sz| ¡ }W n tk
�rØ   d}Y nX |dk	�r||k�r|| }t||ƒjdd�|d< q$| |¡ q$t|f|žŽ S )a  Combine consecutive powers with the same base into one, e.g.
    $$A \times A^2 \Rightarrow A^3$$

    This also cancels out the possible matrix inverses using the
    knowledgebase of :class:`~.Inverse`, e.g.,
    $$ Y \times X \times X^{-1} \Rightarrow Y $$
    r   r   rF   NF)r€   )r7   r]   r[   rY   r   rD   r&   r:   r3   r#   rJ   r|   r‘   r   r   ZOnerc   r   r}   r   r�   )r   r<   r:   Únew_argsr,   ÚAÚBZBargsÚlZAargsr+   rd   ZA_baseZA_expZB_baseZB_expZnew_expZ
B_base_invr/   r/   r0   Úcombine_powersB  sX    




r«   c           	      C   s�   | j }t|ƒ}|dk r| S |d g}td|ƒD ]X}|d }|| }t|tƒr|t|tƒr||j d }|j d }t|| ƒ|d< q.| |¡ q.t|Ž S )zGRefine products of permutation matrices as the products of cycles.
    é   r   r   rF   )r:   r[   r]   rY   r!   r‘   r&   )	r   r:   rª   rh   r,   r¨   r©   Zcycle_1Zcycle_2r/   r/   r0   Úcombine_permutations�  s     

ÿ

r­   c                 C   s�   |   ¡ \}}|d g}|dd… D ]^}|d }t|tƒrBt|tƒsN| |¡ q"| ¡  | t|jd |jd ƒ¡ ||jd 9 }q"t|f|žŽ S )zj
    Combine products of OneMatrix

    e.g. OneMatrix(2, 3) * OneMatrix(3, 4) -> 3 * OneMatrix(2, 4)
    r   r   NrF   )r7   rY   r%   r‘   ÚpoprJ   r�   )r   r<   r:   r§   r©   r¨   r/   r/   r0   Úcombine_one_matrices—  s    

r¯   c                    s‚   | j ‰ tˆ ƒdkr~ddlm} ˆ d jrNˆ d jrN|‡ fdd„ˆ d j D ƒŽ S ˆ d jr~ˆ d jr~|‡ fdd„ˆ d j D ƒŽ S | S )zr
    Simplify MatMul expressions but distributing
    rational term to MatMul.

    e.g. 2*(A+B) -> 2*A + 2*B
    r¬   r   )ÚMatAddr   c                    s   g | ]}t |ˆ d  ƒ ¡ ‘qS r…   ©r&   rc   ©rC   Zmatrœ   r/   r0   rE   ¶  s     z$distribute_monom.<locals>.<listcomp>c                    s   g | ]}t ˆ d  |ƒ ¡ ‘qS )r   r±   r²   rœ   r/   r0   rE   ¸  s     )r:   r[   Zmataddr°   Z	is_MatAddZis_Rational)r   r°   r/   rœ   r0   Údistribute_monom«  s    r³   c                 C   s   | dkS r¥   r/   rŽ   r/   r/   r0   r1   ¼  r2   r1   c                  G   sp   | d j | d jkrtdƒ‚g }d}t| ƒD ]>\}}|j| | j kr,| t| ||d … Ž  ¡ ¡ |d }q,|S )z'factor matrices only if they are squarer   rF   z!Invalid matrices being multipliedr   )rG   rH   ÚRuntimeErrorr_   r‘   r&   rc   )r=   ÚoutÚstartr,   ÚMr/   r/   r0   rz   Á  s    
rz   c                 C   sÀ   g }g }| j D ] }|jr$| |¡ q| |¡ q|d }|dd… D ]h}||jkrrtt |¡|ƒrrt|jd ƒ}qD|| 	¡ kržtt 
|¡|ƒržt|jd ƒ}qD| |¡ |}qD| |¡ t|Ž S )zè
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> expr = X * X.T
    >>> print(expr)
    X*X.T
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(expr))
    I
    r   r   N)r:   rA   r‘   ÚTr   r   Z
orthogonalr#   rJ   Ú	conjugateZunitaryr&   )r?   Zassumptionsr¡   Zexprargsr:   r¢   rD   r/   r/   r0   Úrefine_MatMulÎ  s     


rº   N)AZsympy.assumptions.askr   r   Zsympy.assumptions.refiner   Z
sympy.corer   r   r   Zsympy.core.mulr   r	   Zsympy.core.numbersr
   r   Zsympy.core.symbolr   Zsympy.functionsr   Zsympy.strategiesr   r   r   r   r   r   r   Zsympy.matrices.exceptionsr   Zsympy.matrices.matrixbaser   Zsympy.utilities.exceptionsr   Z!sympy.matrices.expressions._shaper   r8   r}   r   Zmatexprr   Zmatpowr   r    Zpermutationr!   Úspecialr"   r#   r$   r%   r&   Zregister_handlerclassr�   rŸ   r£   r¤   r¦   r«   r­   r¯   r³   Úrulesr>   rz   rº   r/   r/   r/   r0   Ú<module>   sZ   $ V*?      
   þ"