U
    ZÊ¹j\4  ã                   @   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   s0   | st dƒ‚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ÚlenÚKroneckerProductÚdoit)Úmatrices© r    úc/var/www/html/bwave/python/venv/lib/python3.8/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                   sr   t tt|ƒƒ}tdd„ |D ƒƒrTttdd„ |D ƒƒƒ}tdd„ |D ƒƒrP| ¡ S |S |r`t|Ž  tƒ j	| f|žŽ S )Nc                 s   s   | ]}|j V  qd S ©N)Zis_Identity©Ú.0Úar    r    r!   Ú	<genexpr>m   s     z+KroneckerProduct.__new__.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r$   ©Úrowsr%   r    r    r!   r(   n   s     c                 s   s   | ]}t |tƒV  qd S r$   ©Ú
isinstancer   r%   r    r    r!   r(   o   s     )
ÚlistÚmapr   Úallr   r   Zas_explicitÚvalidateÚsuperÚ__new__)Úclsr#   ÚargsÚret©Ú	__class__r    r!   r2   k   s    zKroneckerProduct.__new__c                 C   s@   | j d j\}}| j dd … D ]}||j9 }||j9 }q||fS )Nr   r   )r4   Úshaper*   Úcols)Úselfr*   r9   Úmatr    r    r!   r8   x   s
    
zKroneckerProduct.shapec                 K   sH   d}t | jƒD ]4}t||jƒ\}}t||jƒ\}}||||f 9 }q|S ©Nr   )Úreversedr4   Údivmodr*   r9   )r:   ÚiÚjÚkwargsÚresultr;   ÚmÚnr    r    r!   Ú_entry€   s    zKroneckerProduct._entryc                 C   s   t ttt| jƒƒŽ  ¡ S r$   )r   r-   r.   r   r4   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>Œ   s     z4KroneckerProduct._eval_conjugate.<locals>.<listcomp>)r   r4   r   rF   r    r    r!   Ú_eval_conjugate‹   s    z KroneckerProduct._eval_conjugatec                 C   s   t ttt| jƒƒŽ  ¡ S r$   )r   r-   r.   r
   r4   r   rF   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%   rL   r    r!   rI   “   s     z0KroneckerProduct._eval_trace.<locals>.<listcomp>)rM   r   r4   rF   r    rL   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$   ©Z	is_squarer%   r    r    r!   r(   —   s     z5KroneckerProduct._eval_determinant.<locals>.<genexpr>c                    s   g | ]}ˆ |ƒˆ|j   ‘qS r    r)   r%   ©rO   rC   r    r!   rI   ›   s     z6KroneckerProduct._eval_determinant.<locals>.<listcomp>)ZdeterminantrO   rP   r/   r4   r*   r   )r:   rP   r    rR   r!   Ú_eval_determinant•   s
    z"KroneckerProduct._eval_determinantc                 C   sD   zt dd„ | jD ƒŽ W S  tk
r>   ddlm} || ƒ Y S X d S )Nc                 S   s   g | ]}|  ¡ ‘qS r    )Zinverser%   r    r    r!   rI   Ÿ   s     z2KroneckerProduct._eval_inverse.<locals>.<listcomp>r   )ÚInverse)r   r4   r   Z"sympy.matrices.expressions.inverserT   )r:   rT   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$   ©r8   ©r&   r'   Úbr    r    r!   r(   »   s     z6KroneckerProduct.structurally_equal.<locals>.<genexpr>)r,   r   r8   r   r4   r/   Ú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$   )r9   r*   rW   r    r    r!   r(   Ñ   s     z6KroneckerProduct.has_matching_shape.<locals>.<genexpr>)r,   r   r9   r*   r   r4   r/   rY   rZ   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    rW   r    r    r!   rI   Ø   s     z3KroneckerProduct._kronecker_add.<locals>.<listcomp>)r\   r7   rY   r4   rZ   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    rW   r    r    r!   rI   Þ   s     z3KroneckerProduct._kronecker_mul.<locals>.<listcomp>)r]   r7   rY   r4   rZ   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 ˆ Ž‘qS r    )r   ©r&   Úarg©r^   r    r!   rI   å   s     z)KroneckerProduct.doit.<locals>.<listcomp>)Úgetr4   Úcanonicalizer   )r:   r^   rb   r4   r    re   r!   r   â   s
    zKroneckerProduct.doit)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zis_KroneckerProductr2   Úpropertyr8   rE   rG   rJ   rK   rN   rS   rU   r\   r]   r_   r`   ra   r   Ú__classcell__r    r    r6   r!   r   V   s$   
r   c                  G   s   t dd„ | D ƒƒstdƒ‚d S )Nc                 s   s   | ]}|j V  qd S r$   )Z	is_Matrixrc   r    r    r!   r(   ì   s     zvalidate.<locals>.<genexpr>z Mix of Matrix and Scalar symbols)r/   r   )r4   r    r    r!   r0   ë   s    r0   c                 C   sZ   g }g }| j D ]*}| ¡ \}}| |¡ | t |¡¡ qt|Ž }|dkrV|t|Ž  S | S r<   )r4   Zargs_cncÚextendÚappendr   Z
_from_argsr   )ÚkronZc_partZnc_partrd   ÚcÚncr    r    r!   Úextract_commutativeò   s    

rs   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&   rC   r    r    r!   r(   -  s     z+matrix_kronecker_product.<locals>.<genexpr>z&Sequence of Matrices expected, got: %séÿÿÿÿNr   r   c                 S   s   | j S r$   )Z_class_priority)ÚMr    r    r!   Ú<lambda>I  ó    z*matrix_kronecker_product.<locals>.<lambda>)Úkey)r/   r   Úreprr=   r*   r9   ÚrangeZrow_joinZcol_joinÚmaxr7   r,   )
r   Zmatrix_expansionr;   r*   r9   r?   Ústartr@   Ú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+   rt   r    r    r!   r(   R  s     z-explicit_kronecker_product.<locals>.<genexpr>)r/   r4   r   )rp   r    r    r!   Úexplicit_kronecker_productP  s    r€   c                 C   s
   t | tƒS r$   )r,   r   )Úxr    r    r!   rw   ]  rx   rw   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$   rV   r%   r    r    r!   r(   c  s     z&_kronecker_dims_key.<locals>.<genexpr>©r   )r,   r   Útupler4   ©Úexprr    r    r!   Ú_kronecker_dims_keya  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$   )r`   )r�   Úyr    r    r!   rw   n  rx   z.kronecker_mat_add.<locals>.<listcomp>.<lambda>r   )r&   Úgroupr    r    r!   rI   n  s   ÿz%kronecker_mat_add.<locals>.<listcomp>)r   r4   r†   ÚpopÚvaluesr   )r…   r4   ZnonkronsZkronsr    r    r!   Úkronecker_mat_addh  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   é   )Zas_coeff_matricesr   r,   r   ra   r‰   r   )r…   Úfactorr   r?   ÚAÚBr    r    r!   Úkronecker_mat_mulw  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$   rQ   r%   r    r    r!   r(   ˆ  s     z$kronecker_mat_pow.<locals>.<genexpr>c                    s   g | ]}t |ˆ jƒ‘qS r    )r   Úexpr%   r„   r    r!   rI   ‰  s     z%kronecker_mat_pow.<locals>.<listcomp>)r,   Úbaser   r/   r4   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k	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•   ÚrulerB   r   r    r    r!   Úcombine_kroneckerŽ  s     
  þÿÿr˜   N)4rk   Ú	functoolsr   Úmathr   Z
sympy.corer   r   Zsympy.functionsr   Zsympy.matrices.exceptionsr   Z"sympy.matrices.expressions.matexprr	   Z$sympy.matrices.expressions.transposer
   Z"sympy.matrices.expressions.specialr   Zsympy.matrices.matrixbaser   Zsympy.strategiesr   r   r   r   r   r   r   r   Zsympy.strategies.traverser   Zsympy.utilitiesr   Zmataddr   Úmatmulr   Zmatpowr   r"   r   r0   rs   r   r€   Úrulesrg   r†   r‹   r�   r“   r˜   r    r    r    r!   Ú<module>   sF   (@ Pý
ÿ