B
    [#                 @   sP  d dl mZmZ d dlmZ d dl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mZmZmZmZmZmZ d dlmZmZmZmZ d d	lmZ G d
d deZdd Z dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&e"e%e$eedd e#e&efZ'eeeee' iZ(dd Z)d dl*m+Z+m,Z, d dl-m.Z. d d! Z/e/e.d< d"S )#    )print_functiondivision)Number)MulBasicsympifyAdd)range)adjoint)	transpose)rm_idunpacktypedflattenexhaustdo_onenew)
MatrixExpr
ShapeErrorIdentity
ZeroMatrix)
MatrixBasec               @   sz   e Zd ZdZdZdd Zedd ZdddZd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd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
    Tc             O   sN   | dd}ttt|}tj| f| }| \}}|rBt|  |sJ|S |S )NcheckT)getlistmapr   r   __new__as_coeff_matricesvalidate)clsargskwargsr   objfactormatrices r&   @lib/python3.7/site-packages/sympy/matrices/expressions/matmul.pyr      s    zMatMul.__new__c             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&   r'   
<listcomp>-   s    z MatMul.shape.<locals>.<listcomp>r   )r!   rowscols)selfr%   r&   r&   r'   shape+   s    zMatMul.shapec                sj  ddl m}m}m}m m |  \}}t|dkrH||d ||f  S d gt|d  d gt|d  }	|d< |d< x&tdt|D ]}|d| |< qW x.t	|d d D ]\}}
|
j
d d |	|< qW fddt	|D }||}t fdd	|D rd
}|||ftdd dgt|	 |	  }tfdd	|	D sXd}|rf| S |S )Nr   )DummySumr   ImmutableMatrixInteger   r,   zi_%ic                s(   g | ] \}}| |  |d   f qS )r5   r&   )r)   ir*   )indicesr&   r'   r+   @   s    z!MatMul._entry.<locals>.<listcomp>c             3   s   | ]}|  V  qd S )N)Zhas)r)   v)r3   r&   r'   	<genexpr>B   s    z MatMul._entry.<locals>.<genexpr>Tc             3   s   | ]}t | tfV  qd S )N)
isinstanceint)r)   r8   )r4   r&   r'   r9   J   s    F)sympyr1   r2   r   r3   r4   r   lenr	   	enumerater0   Zfromiteranyzipdoit)r/   r6   jexpandr1   r2   r   coeffr%   Z
ind_rangesr*   Zexpr_in_sumresultr&   )r3   r4   r7   r'   _entry0   s,    
$zMatMul._entryc             C   s0   dd | j D }dd | j D }t| }||fS )Nc             S   s   g | ]}|j s|qS r&   )r(   )r)   xr&   r&   r'   r+   O   s    z,MatMul.as_coeff_matrices.<locals>.<listcomp>c             S   s   g | ]}|j r|qS r&   )r(   )r)   rG   r&   r&   r'   r+   P   s    )r!   r   )r/   Zscalarsr%   rD   r&   r&   r'   r   N   s    zMatMul.as_coeff_matricesc             C   s   |   \}}|t| fS )N)r   r   )r/   rD   r%   r&   r&   r'   as_coeff_mmulU   s    zMatMul.as_coeff_mmulc             C   s"   t dd | jd d d D   S )Nc             S   s   g | ]}t |qS r&   )r   )r)   r*   r&   r&   r'   r+   Z   s    z*MatMul._eval_transpose.<locals>.<listcomp>r,   )r   r!   rA   )r/   r&   r&   r'   _eval_transposeY   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
   )r)   r*   r&   r&   r'   r+   ]   s    z(MatMul._eval_adjoint.<locals>.<listcomp>r,   )r   r!   rA   )r/   r&   r&   r'   _eval_adjoint\   s    zMatMul._eval_adjointc             C   s<   |   \}}|dkr0ddlm} |||  S tdd S )Nr5   )tracezCan't simplify any further)rH   rK   rA   NotImplementedError)r/   r$   mmulrK   r&   r&   r'   _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.determinantrO   r   only_squaresr-   r   r   r   )r/   rO   r$   r%   Zsquare_matricesr&   r&   r'   _eval_determinantg   s    zMatMul._eval_determinantc             C   sL   y"t dd | jd d d D   S  tk
rF   ddlm} || S X d S )Nc             S   s&   g | ]}t |tr| n|d  qS )r,   )r:   r   inverse)r)   r*   r&   r&   r'   r+   p   s   z(MatMul._eval_inverse.<locals>.<listcomp>r,   r   )Inverse)r   r!   rA   r   Z"sympy.matrices.expressions.inverserS   )r/   rS   r&   r&   r'   _eval_inversem   s    zMatMul._eval_inversec                s8     dd}|r& fdd| jD }n| j}tt| S )NdeepTc                s   g | ]}|j f  qS r&   )rA   )r)   r*   )r"   r&   r'   r+   y   s    zMatMul.doit.<locals>.<listcomp>)r   r!   canonicalizer   )r/   r"   rU   r!   r&   )r"   r'   rA   v   s
    zMatMul.doitc             K   s(   |   \}}|jf |\}}||| fS )N)r   args_cnc)r/   r"   rD   r%   Zcoeff_cZcoeff_ncr&   r&   r'   rW      s    zMatMul.args_cncN)T)__name__
__module____qualname____doc__Z	is_MatMulr   propertyr0   rF   r   rH   rI   rJ   rN   rQ   rT   rA   rW   r&   r&   r&   r'   r      s   
		r   c              G   sN   xHt t| d D ]4}| ||d  \}}|j|jkrtd||f qW dS )z, Checks for valid shapes for args of MatMul r5      z"Matrices %s and %s are not alignedN)r	   r=   r.   r-   r   )r%   r6   ABr&   r&   r'   r      s    r   c              G   s&   | d dkr| dd  } t tf|  S )Nr   r5   )r   r   )r!   r&   r&   r'   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   g | ]}|j p|jo|jqS r&   )Zis_zeror(   Zis_ZeroMatrix)r)   r*   r&   r&   r'   r+      s   zany_zeros.<locals>.<listcomp>c             S   s   g | ]}|j r|qS r&   )r(   )r)   r*   r&   r&   r'   r+      s    r   r,   )r?   r!   r   r-   r.   )mulr%   r&   r&   r'   	any_zeros   s
    rb   c             C   s   t dd | jD s| S g }| jd }xJ| jdd D ]8}t|ttfr`t|ttfr`|| }q6|| |}q6W || t| S )a   Merge explicit MatrixBase arguments

    >>> from sympy import MatrixSymbol, eye, 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 )N)r:   r   )r)   r*   r&   r&   r'   r9      s    z!merge_explicit.<locals>.<genexpr>r   r5   N)r?   r!   r:   r   r   appendr   )matmulnewargslastr*   r&   r&   r'   merge_explicit   s    



rg   c          	   C   s   |   \}}xtt|dd |dd D ]t\}\}}yR|jr|jr|| krt|j}t|f|d| |g ||d d   S W q, tk
r   Y q,X q,W | S )z Y * X * X.I -> Y Nr,   r5   r]   )	r   r>   r@   Z	is_squarerR   r   r-   r`   
ValueError)ra   r$   r%   r6   XYIr&   r&   r'   xxinv   s    ,
0
rl   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_Identity)rG   r&   r&   r'   <lambda>   s    zremove_ids.<locals>.<lambda>N)rH   r   r`   r!   )ra   r$   rM   rE   r&   r&   r'   
remove_ids   s
    rn   c             C   s&   |   \}}|dkr"t|f| S | S )Nr5   )r   r`   )ra   r$   r%   r&   r&   r'   factor_in_front   s    ro   c             C   s   | dkS )Nr5   r&   )rG   r&   r&   r'   rm      s    rm   c              G   st   | d j | d jkrtdg }d}xJt| D ]>\}}|j| | j kr.|t| ||d     |d }q.W |S )z) factor matrices only if they are square r   r,   z!Invalid matrices being multipliedr5   )r-   r.   RuntimeErrorr>   rc   r   rA   )r%   outstartr6   Mr&   r&   r'   rP      s    rP   )askQ)handlers_dictc             C   s   g }g }x*| j D ] }|jr&|| q|| qW |d }xx|dd D ]h}||jkrxtt||rxt|jd }qJ||	 krtt
||rt|jd }qJ|| |}qJW || 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   r5   N)r!   r(   rc   Trt   ru   Z
orthogonalr   r0   	conjugateZunitaryr   )exprZassumptionsre   Zexprargsr!   rf   r*   r&   r&   r'   refine_MatMul  s     

rz   N)0Z
__future__r   r   r<   r   Z
sympy.corer   r   r   r   Zsympy.core.compatibilityr	   Zsympy.functionsr
   Z$sympy.matrices.expressions.transposer   Zsympy.strategiesr   r   r   r   r   r   r   Z"sympy.matrices.expressions.matexprr   r   r   r   Zsympy.matrices.matricesr   r   r   r`   rb   rg   rl   rn   ro   ZrulesrV   rP   Zsympy.assumptions.askrt   ru   Zsympy.assumptions.refinerv   rz   r&   r&   r&   r'   <module>   s0   $y
*
"