U
    9%e<                     @   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/Darija-Ai-API/env/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|< qt	|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   s<   |   \}}|dkr0ddlm} |||  S tdd S )Nr   )tracezCan't simplify any further)rn   rv   rc   rl   )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 }|rt fddt|D }nt| jd }| j| 	}	|	D ]"}
|

| |
| ||
 qq,|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   8  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rt|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 ]}|
||< qq$|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_powersD  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   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rtt
||rt|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.commonr   Zsympy.matrices.matricesr   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   $ X*?      
   "