a
    RG5dn4                     @   s^  d Z ddlmZ ddl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 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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 Z'G dd deZ(dd Z)dd Z*dd Z+dd Z,ee,ee*fZ-eedd ee- Z.d d! Z/d"d# Z0d$d% Z1d&d' Z2d(d) Z3d*S )+z'Implementation of the Kronecker product    reduce)prod)Mulsympify)adjoint)
ShapeError)
MatrixExpr)	transpose)Identity)
MatrixBase)canon	condition
distributedo_oneexhaustflattentypedunpack)	bottom_up)sift   )MatAdd)MatMul)MatPowc                  G   s8   | st dt|   t| dkr(| d S t|   S dS )aT  
    The Kronecker product of two or more arguments.

    This computes the explicit Kronecker product for subclasses of
    ``MatrixBase`` i.e. explicit matrices. Otherwise, a symbolic
    ``KroneckerProduct`` object is returned.


    Examples
    ========

    For ``MatrixSymbol`` arguments a ``KroneckerProduct`` object is returned.
    Elements of this matrix can be obtained by indexing, or for MatrixSymbols
    with known dimension the explicit matrix can be obtained with
    ``.as_explicit()``

    >>> from sympy import kronecker_product, MatrixSymbol
    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = MatrixSymbol('B', 2, 2)
    >>> kronecker_product(A)
    A
    >>> kronecker_product(A, B)
    KroneckerProduct(A, B)
    >>> kronecker_product(A, B)[0, 1]
    A[0, 0]*B[0, 1]
    >>> kronecker_product(A, B).as_explicit()
    Matrix([
        [A[0, 0]*B[0, 0], A[0, 0]*B[0, 1], A[0, 1]*B[0, 0], A[0, 1]*B[0, 1]],
        [A[0, 0]*B[1, 0], A[0, 0]*B[1, 1], A[0, 1]*B[1, 0], A[0, 1]*B[1, 1]],
        [A[1, 0]*B[0, 0], A[1, 0]*B[0, 1], A[1, 1]*B[0, 0], A[1, 1]*B[0, 1]],
        [A[1, 0]*B[1, 0], A[1, 0]*B[1, 1], A[1, 1]*B[1, 0], A[1, 1]*B[1, 1]]])

    For explicit matrices the Kronecker product is returned as a Matrix

    >>> from sympy import Matrix, kronecker_product
    >>> sigma_x = Matrix([
    ... [0, 1],
    ... [1, 0]])
    ...
    >>> Isigma_y = Matrix([
    ... [0, 1],
    ... [-1, 0]])
    ...
    >>> kronecker_product(sigma_x, Isigma_y)
    Matrix([
    [ 0, 0,  0, 1],
    [ 0, 0, -1, 0],
    [ 0, 1,  0, 0],
    [-1, 0,  0, 0]])

    See Also
    ========
        KroneckerProduct

    z$Empty Kronecker product is undefinedr   r   N)	TypeErrorvalidatelenKroneckerProductdoit)matrices r!   `/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/matrices/expressions/kronecker.pykronecker_product   s    8r#   c                       s   e Zd ZdZdZdd fdd
Ze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d Zdd Zdd Zd d! Z  ZS )"r   a  
    The Kronecker product of two or more arguments.

    The Kronecker product is a non-commutative product of matrices.
    Given two matrices of dimension (m, n) and (s, t) it produces a matrix
    of dimension (m s, n t).

    This is a symbolic object that simply stores its argument without
    evaluating it. To actually compute the product, use the function
    ``kronecker_product()`` or call the ``.doit()`` or  ``.as_explicit()``
    methods.

    >>> from sympy import KroneckerProduct, MatrixSymbol
    >>> A = MatrixSymbol('A', 5, 5)
    >>> B = MatrixSymbol('B', 5, 5)
    >>> isinstance(KroneckerProduct(A, B), KroneckerProduct)
    True
    T)checkc                   st   t tt|}tdd |D rTttdd |D }tdd |D rP| S |S |r`t|  t j	| g|R  S )Nc                 s   s   | ]}|j V  qd S N)is_Identity.0ar!   r!   r"   	<genexpr>n       z+KroneckerProduct.__new__.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r%   rowsr'   r!   r!   r"   r*   o   r+   c                 s   s   | ]}t |tV  qd S r%   
isinstancer   r'   r!   r!   r"   r*   p   r+   )
listmapr   allr   r   as_explicitr   super__new__)clsr$   argsret	__class__r!   r"   r5   l   s    zKroneckerProduct.__new__c                 C   s@   | j d j\}}| j dd  D ]}||j9 }||j9 }q||fS )Nr   r   )r7   shaper-   cols)selfr-   r<   matr!   r!   r"   r;   y   s
    
zKroneckerProduct.shapec                 K   sH   d}t | jD ]4}t||j\}}t||j\}}||||f 9 }q|S Nr   )reversedr7   divmodr-   r<   )r=   ijkwargsresultr>   mnr!   r!   r"   _entry   s    zKroneckerProduct._entryc                 C   s   t ttt| j  S r%   )r   r0   r1   r   r7   r   r=   r!   r!   r"   _eval_adjoint   s    zKroneckerProduct._eval_adjointc                 C   s   t dd | jD   S )Nc                 S   s   g | ]}|  qS r!   )	conjugater'   r!   r!   r"   
<listcomp>   r+   z4KroneckerProduct._eval_conjugate.<locals>.<listcomp>)r   r7   r   rI   r!   r!   r"   _eval_conjugate   s    z KroneckerProduct._eval_conjugatec                 C   s   t ttt| j  S r%   )r   r0   r1   r
   r7   r   rI   r!   r!   r"   _eval_transpose   s    z KroneckerProduct._eval_transposec                    s$   ddl m   t fdd| jD  S )Nr   tracec                    s   g | ]} |qS r!   r!   r'   rO   r!   r"   rL      r+   z0KroneckerProduct._eval_trace.<locals>.<listcomp>)rP   r   r7   rI   r!   rO   r"   _eval_trace   s    zKroneckerProduct._eval_tracec                    sL   ddl m m} tdd | jD s,|| S | jt fdd| jD  S )Nr   )detDeterminantc                 s   s   | ]}|j V  qd S r%   	is_squarer'   r!   r!   r"   r*      r+   z5KroneckerProduct._eval_determinant.<locals>.<genexpr>c                    s   g | ]} ||j   qS r!   r,   r'   rR   rF   r!   r"   rL      r+   z6KroneckerProduct._eval_determinant.<locals>.<listcomp>)determinantrR   rS   r2   r7   r-   r   )r=   rS   r!   rV   r"   _eval_determinant   s
    z"KroneckerProduct._eval_determinantc                 C   sB   zt dd | jD  W S  ty<   ddlm} ||  Y S 0 d S )Nc                 S   s   g | ]}|  qS r!   )inverser'   r!   r!   r"   rL      r+   z2KroneckerProduct._eval_inverse.<locals>.<listcomp>r   )Inverse)r   r7   r   Z"sympy.matrices.expressions.inverserZ   )r=   rZ   r!   r!   r"   _eval_inverse   s
    zKroneckerProduct._eval_inversec                 C   sF   t |toD| j|jkoDt| jt|jkoDtdd t| j|jD S )a  Determine whether two matrices have the same Kronecker product structure

        Examples
        ========

        >>> from sympy import KroneckerProduct, MatrixSymbol, symbols
        >>> m, n = symbols(r'm, n', integer=True)
        >>> A = MatrixSymbol('A', m, m)
        >>> B = MatrixSymbol('B', n, n)
        >>> C = MatrixSymbol('C', m, m)
        >>> D = MatrixSymbol('D', n, n)
        >>> KroneckerProduct(A, B).structurally_equal(KroneckerProduct(C, D))
        True
        >>> KroneckerProduct(A, B).structurally_equal(KroneckerProduct(D, C))
        False
        >>> KroneckerProduct(A, B).structurally_equal(C)
        False
        c                 s   s   | ]\}}|j |j kV  qd S r%   r;   r(   r)   br!   r!   r"   r*      r+   z6KroneckerProduct.structurally_equal.<locals>.<genexpr>)r/   r   r;   r   r7   r2   zipr=   otherr!   r!   r"   structurally_equal   s    

z#KroneckerProduct.structurally_equalc                 C   sF   t |toD| j|jkoDt| jt|jkoDtdd t| j|jD S )aq  Determine whether two matrices have the appropriate structure to bring matrix
        multiplication inside the KroneckerProdut

        Examples
        ========
        >>> from sympy import KroneckerProduct, MatrixSymbol, symbols
        >>> m, n = symbols(r'm, n', integer=True)
        >>> A = MatrixSymbol('A', m, n)
        >>> B = MatrixSymbol('B', n, m)
        >>> KroneckerProduct(A, B).has_matching_shape(KroneckerProduct(B, A))
        True
        >>> KroneckerProduct(A, B).has_matching_shape(KroneckerProduct(A, B))
        False
        >>> KroneckerProduct(A, B).has_matching_shape(A)
        False
        c                 s   s   | ]\}}|j |jkV  qd S r%   )r<   r-   r]   r!   r!   r"   r*      r+   z6KroneckerProduct.has_matching_shape.<locals>.<genexpr>)r/   r   r<   r-   r   r7   r2   r_   r`   r!   r!   r"   has_matching_shape   s    

z#KroneckerProduct.has_matching_shapec                 K   s   t tttttti| S r%   )r   r   r   r   r   r   )r=   hintsr!   r!   r"   _eval_expand_kroneckerproduct   s    z.KroneckerProduct._eval_expand_kroneckerproductc                 C   s4   |  |r(| jdd t| j|jD  S | | S d S )Nc                 S   s   g | ]\}}|| qS r!   r!   r]   r!   r!   r"   rL      r+   z3KroneckerProduct._kronecker_add.<locals>.<listcomp>)rb   r:   r_   r7   r`   r!   r!   r"   _kronecker_add   s    
zKroneckerProduct._kronecker_addc                 C   s4   |  |r(| jdd t| j|jD  S | | S d S )Nc                 S   s   g | ]\}}|| qS r!   r!   r]   r!   r!   r"   rL      r+   z3KroneckerProduct._kronecker_mul.<locals>.<listcomp>)rc   r:   r_   r7   r`   r!   r!   r"   _kronecker_mul   s    
zKroneckerProduct._kronecker_mulc                    s8     dd}|r& fdd| jD }n| j}tt| S )NdeepTc                    s   g | ]}|j f i  qS r!   )r   r(   argrd   r!   r"   rL      r+   z)KroneckerProduct.doit.<locals>.<listcomp>)getr7   canonicalizer   )r=   rd   rh   r7   r!   rk   r"   r      s
    zKroneckerProduct.doit)__name__
__module____qualname____doc__Zis_KroneckerProductr5   propertyr;   rH   rJ   rM   rN   rQ   rX   r[   rb   rc   re   rf   rg   r   __classcell__r!   r!   r9   r"   r   W   s$   
r   c                  G   s   t dd | D stdd S )Nc                 s   s   | ]}|j V  qd S r%   )	is_Matrixri   r!   r!   r"   r*      r+   zvalidate.<locals>.<genexpr>z Mix of Matrix and Scalar symbols)r2   r   )r7   r!   r!   r"   r      s    r   c                 C   sZ   g }g }| j D ]*}| \}}|| |t| qt| }|dkrV|t|  S | S r?   )r7   args_cncextendappendr   
_from_argsr   )kronc_partnc_partrj   cncr!   r!   r"   extract_commutative   s    

r~   c            
   	   G   s   t dd | D s"tdt|  | d }t| dd D ]z}|j}|j}t|D ]\}||||   }t|d D ]"}||||| | d   }qr|dkr|}qR||}qR|}q:t	| dd	 d
j
}	t||	r|S |	|S dS )a  Compute the Kronecker product of a sequence of SymPy Matrices.

    This is the standard Kronecker product of matrices [1].

    Parameters
    ==========

    matrices : tuple of MatrixBase instances
        The matrices to take the Kronecker product of.

    Returns
    =======

    matrix : MatrixBase
        The Kronecker product matrix.

    Examples
    ========

    >>> from sympy import Matrix
    >>> from sympy.matrices.expressions.kronecker import (
    ... matrix_kronecker_product)

    >>> m1 = Matrix([[1,2],[3,4]])
    >>> m2 = Matrix([[1,0],[0,1]])
    >>> matrix_kronecker_product(m1, m2)
    Matrix([
    [1, 0, 2, 0],
    [0, 1, 0, 2],
    [3, 0, 4, 0],
    [0, 3, 0, 4]])
    >>> matrix_kronecker_product(m2, m1)
    Matrix([
    [1, 2, 0, 0],
    [3, 4, 0, 0],
    [0, 0, 1, 2],
    [0, 0, 3, 4]])

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Kronecker_product
    c                 s   s   | ]}t |tV  qd S r%   r.   r(   rF   r!   r!   r"   r*   .  r+   z+matrix_kronecker_product.<locals>.<genexpr>z&Sequence of Matrices expected, got: %sNr   r   c                 S   s   | j S r%   )_class_priority)Mr!   r!   r"   <lambda>J  r+   z*matrix_kronecker_product.<locals>.<lambda>)key)r2   r   reprr@   r-   r<   rangerow_joincol_joinmaxr:   r/   )
r    Zmatrix_expansionr>   r-   r<   rB   startrC   nextZMatrixClassr!   r!   r"   matrix_kronecker_product  s,    -

r   c                 C   s"   t dd | jD s| S t| j S )Nc                 s   s   | ]}t |tV  qd S r%   r.   r   r!   r!   r"   r*   S  r+   z-explicit_kronecker_product.<locals>.<genexpr>)r2   r7   r   )ry   r!   r!   r"   explicit_kronecker_productQ  s    r   c                 C   s
   t | tS r%   )r/   r   )xr!   r!   r"   r   ^  r+   r   c                 C   s&   t | trtdd | jD S dS d S )Nc                 s   s   | ]}|j V  qd S r%   r\   r'   r!   r!   r"   r*   d  r+   z&_kronecker_dims_key.<locals>.<genexpr>r   )r/   r   tupler7   exprr!   r!   r"   _kronecker_dims_keyb  s    
r   c                 C   sN   t | jt}|dd }|s | S dd | D }|s>t| S t| | S d S )Nr   c                 S   s   g | ]}t d d |qS )c                 S   s
   |  |S r%   )rf   )r   yr!   r!   r"   r   o  r+   z.kronecker_mat_add.<locals>.<listcomp>.<lambda>r   )r(   groupr!   r!   r"   rL   o  s   z%kronecker_mat_add.<locals>.<listcomp>)r   r7   r   popvaluesr   )r   r7   ZnonkronsZkronsr!   r!   r"   kronecker_mat_addi  s    r   c                 C   s|   |   \}}d}|t|d k rp|||d  \}}t|trft|trf||||< ||d  q|d7 }q|t|  S )Nr   r      )as_coeff_matricesr   r/   r   rg   r   r   )r   factorr    rB   ABr!   r!   r"   kronecker_mat_mulx  s    
r   c                    sD   t  jtr<tdd  jjD r<t fdd jjD  S  S d S )Nc                 s   s   | ]}|j V  qd S r%   rT   r'   r!   r!   r"   r*     r+   z$kronecker_mat_pow.<locals>.<genexpr>c                    s   g | ]}t | jqS r!   )r   expr'   r   r!   r"   rL     r+   z%kronecker_mat_pow.<locals>.<listcomp>)r/   baser   r2   r7   r   r!   r   r"   kronecker_mat_pow  s    "r   c                 C   sX   dd }t tt t|ttttttt	i}|| }t
|dd}|durP| S |S dS )a-  Combine KronekeckerProduct with expression.

    If possible write operations on KroneckerProducts of compatible shapes
    as a single KroneckerProduct.

    Examples
    ========

    >>> from sympy.matrices.expressions import combine_kronecker
    >>> from sympy import MatrixSymbol, KroneckerProduct, symbols
    >>> m, n = symbols(r'm, n', integer=True)
    >>> A = MatrixSymbol('A', m, n)
    >>> B = MatrixSymbol('B', n, m)
    >>> combine_kronecker(KroneckerProduct(A, B)*KroneckerProduct(B, A))
    KroneckerProduct(A*B, B*A)
    >>> combine_kronecker(KroneckerProduct(A, B)+KroneckerProduct(B.T, A.T))
    KroneckerProduct(A + B.T, B + A.T)
    >>> C = MatrixSymbol('C', n, n)
    >>> D = MatrixSymbol('D', m, m)
    >>> combine_kronecker(KroneckerProduct(C, D)**m)
    KroneckerProduct(C**m, D**m)
    c                 S   s   t | to| tS r%   )r/   r	   hasr   r   r!   r!   r"   haskron  s    z"combine_kronecker.<locals>.haskronr   N)r   r   r   r   r   r   r   r   r   r   getattr)r   r   rulerE   r   r!   r!   r"   combine_kronecker  s    
r   N)4rq   	functoolsr   mathr   
sympy.corer   r   sympy.functionsr   sympy.matrices.commonr   "sympy.matrices.expressions.matexprr	   $sympy.matrices.expressions.transposer
   Z"sympy.matrices.expressions.specialr   sympy.matrices.matricesr   sympy.strategiesr   r   r   r   r   r   r   r   Zsympy.strategies.traverser   sympy.utilitiesr   mataddr   matmulr   matpowr   r#   r   r   r~   r   r   rulesrm   r   r   r   r   r   r!   r!   r!   r"   <module>   sF   (A P
