
    Edn4                     t   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 Z' G d de          Z(d Z)d Z*d Z+d Z,ee,ee*fZ- e ed  ee-                     Z.d Z/d Z0d Z1d Z2d 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                      | st          d          t          |   t          |           dk    r| d         S t          |                                  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   )	TypeErrorvalidatelenKroneckerProductdoit)matricess    Dlib/python3.11/site-packages/sympy/matrices/expressions/kronecker.pykronecker_productr$      s\    p  @>???h
8}} 2{*//111    c                        e Zd ZdZdZdd fd
Zed             Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Z x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                n   t          t          t          |                    }t          d |D                       rUt	          t          d |D                                 }t          d |D                       r|                                S |S |r	t          |   t                      j	        | g|R  S )Nc              3   $   K   | ]}|j         V  d S N)is_Identity.0as     r#   	<genexpr>z+KroneckerProduct.__new__.<locals>.<genexpr>n   s$      ++q}++++++r%   c              3   $   K   | ]}|j         V  d S r*   rowsr,   s     r#   r/   z+KroneckerProduct.__new__.<locals>.<genexpr>o   s$      551555555r%   c              3   @   K   | ]}t          |t                    V  d S r*   
isinstancer   r,   s     r#   r/   z+KroneckerProduct.__new__.<locals>.<genexpr>p   s,      ;;:a,,;;;;;;r%   )
listmapr   allr   r   as_explicitr   super__new__)clsr'   argsret	__class__s       r#   r;   zKroneckerProduct.__new__l   s    C&&''++d+++++ 	4555555566C;;d;;;;; (((
 	dOOuwws*T****r%   c                     | j         d         j        \  }}| j         dd          D ]}||j        z  }||j        z  }||fS )Nr   r   )r=   shaper2   cols)selfr2   rB   mats       r#   rA   zKroneckerProduct.shapey   sQ    Yq\'
d9QRR= 	 	CCHDCHDDd|r%   c                     d}t          | j                  D ]?}t          ||j                  \  }}t          ||j                  \  }}||||f         z  }@|S Nr   )reversedr=   divmodr2   rB   )rC   ijkwargsresultrD   mns           r#   _entryzKroneckerProduct._entry   sc    DI&& 	  	 C!SX&&DAq!SX&&DAqc!Q$iFFr%   c                     t          t          t          t          | j                                                             S r*   )r    r6   r7   r   r=   r!   rC   s    r#   _eval_adjointzKroneckerProduct._eval_adjoint   s-    c'49&=&=!>!>?DDFFFr%   c                 V    t          d | j        D                                              S )Nc                 6    g | ]}|                                 S  )	conjugater,   s     r#   
<listcomp>z4KroneckerProduct._eval_conjugate.<locals>.<listcomp>   s     !C!C!CA!++--!C!C!Cr%   )r    r=   r!   rQ   s    r#   _eval_conjugatez KroneckerProduct._eval_conjugate   s*    !C!C!C!C!CDIIKKKr%   c                     t          t          t          t          | j                                                             S r*   )r    r6   r7   r   r=   r!   rQ   s    r#   _eval_transposez KroneckerProduct._eval_transpose   s-    c)TY&?&?!@!@AFFHHHr%   c                 D    ddl m  t          fd| j        D              S )Nr   )tracec                 &    g | ]} |          S rU   rU   )r-   r.   r\   s     r#   rW   z0KroneckerProduct._eval_trace.<locals>.<listcomp>   s!    111!UU1XX111r%   )r\   r   r=   )rC   r\   s    @r#   _eval_tracezKroneckerProduct._eval_trace   s7          1111ty11122r%   c                     ddl mm} t          d | j        D                       s ||           S | j        t          fd| j        D              S )Nr   )detDeterminantc              3   $   K   | ]}|j         V  d S r*   	is_squarer,   s     r#   r/   z5KroneckerProduct._eval_determinant.<locals>.<genexpr>   s$      2211;222222r%   c                 <    g | ]} |          |j         z  z  S rU   r1   )r-   r.   r`   rM   s     r#   rW   z6KroneckerProduct._eval_determinant.<locals>.<listcomp>   s,    ;;;ASSVVah';;;r%   )determinantr`   ra   r8   r=   r2   r   )rC   ra   r`   rM   s     @@r#   _eval_determinantz"KroneckerProduct._eval_determinant   sy    1111111122	22222 	%;t$$$I;;;;;;;;<<r%   c                 v    	 t          d | j        D              S # t          $ r ddlm}  ||           cY S w xY w)Nc                 6    g | ]}|                                 S rU   )inverser,   s     r#   rW   z2KroneckerProduct._eval_inverse.<locals>.<listcomp>   s     %E%E%Eaaiikk%E%E%Er%   r   )Inverse)r    r=   r	   "sympy.matrices.expressions.inverserk   )rC   rk   s     r#   _eval_inversezKroneckerProduct._eval_inverse   sd    	!#%E%E49%E%E%EFF 	! 	! 	!BBBBBB74==   	!s    88c                    t          |t                    oj| j        |j        k    oZt          | j                  t          |j                  k    o0t          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              3   <   K   | ]\  }}|j         |j         k    V  d S r*   rA   r-   r.   bs      r#   r/   z6KroneckerProduct.structurally_equal.<locals>.<genexpr>   s/      TTv117*TTTTTTr%   )r5   r    rA   r   r=   r8   ziprC   others     r#   structurally_equalz#KroneckerProduct.structurally_equal   sx    ( 5"233 UJ%+-U	NNc%*oo5U TTTY
9S9STTTTT	Vr%   c                    t          |t                    oj| j        |j        k    oZt	          | j                  t	          |j                  k    o0t          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              3   <   K   | ]\  }}|j         |j        k    V  d S r*   )rB   r2   rq   s      r#   r/   z6KroneckerProduct.has_matching_shape.<locals>.<genexpr>   s/      RRVa!&(RRRRRRr%   )r5   r    rB   r2   r   r=   r8   rs   rt   s     r#   has_matching_shapez#KroneckerProduct.has_matching_shape   sx    " 5"233 SI+S	NNc%*oo5S RRs49ej7Q7QRRRRR	Tr%   c                     t           t          t          t          t	          t          t
                    i                    |                     S r*   )r   r   r   r    r   r   )rC   hintss     r#   _eval_expand_kroneckerproductz.KroneckerProduct._eval_expand_kroneckerproduct   s>    ]uU$4jAQSY6Z6Z#[\\]]^bccdddr%   c                     |                      |          r, | j        d t          | j        |j                  D              S | |z   S )Nc                     g | ]
\  }}||z   S rU   rU   rq   s      r#   rW   z3KroneckerProduct._kronecker_add.<locals>.<listcomp>   s     #S#S#Sfq!AE#S#S#Sr%   )rv   r?   rs   r=   rt   s     r#   _kronecker_addzKroneckerProduct._kronecker_add   sN    ""5)) 	 !4>#S#SDIuz8R8R#S#S#STT%<r%   c                     |                      |          r, | j        d t          | j        |j                  D              S | |z  S )Nc                     g | ]
\  }}||z  S rU   rU   rq   s      r#   rW   z3KroneckerProduct._kronecker_mul.<locals>.<listcomp>   s     #Q#Q#QFQAaC#Q#Q#Qr%   )ry   r?   rs   r=   rt   s     r#   _kronecker_mulzKroneckerProduct._kronecker_mul   sN    ""5)) 	 !4>#Q#Qc$)UZ6P6P#Q#Q#QRR%<r%   c                                          dd          }|rfd| j        D             }n| j        }t          t          |           S )NdeepTc                 *    g | ]} |j         d i S )rU   )r!   )r-   argr{   s     r#   rW   z)KroneckerProduct.doit.<locals>.<listcomp>   s+    ;;;#HCH%%u%%;;;r%   )getr=   canonicalizer    )rC   r{   r   r=   s    `  r#   r!   zKroneckerProduct.doit   sV    yy&& 	;;;;;;;DD9D,d3444r%   )__name__
__module____qualname____doc__is_KroneckerProductr;   propertyrA   rO   rR   rX   rZ   r^   rg   rm   rv   ry   r|   r   r   r!   __classcell__)r?   s   @r#   r    r    W   sG        $ "& + + + + + + +   X  G G GL L LI I I3 3 3= = =! ! !V V V2T T T,e e e          5 5 5 5 5 5 5r%   r    c                  V    t          d | D                       st          d          d S )Nc              3   $   K   | ]}|j         V  d S r*   )	is_Matrix)r-   r   s     r#   r/   zvalidate.<locals>.<genexpr>   s$      --s}------r%   z Mix of Matrix and Scalar symbols)r8   r   )r=   s    r#   r   r      s:    ------- <:;;;< <r%   c                     g }g }| j         D ]U}|                                \  }}|                    |           |                    t	          j        |                     Vt	          | }|dk    r|t          | z  S | S rF   )r=   args_cncextendappendr   
_from_argsr    )kronc_partnc_partr   cncs         r#   extract_commutativer      s    FGy + +2as~b))****&\F{ 1&000Kr%   c            	      2   t          d | D                       st          dt          |           z            | d         }t          | dd                   D ]}|j        }|j        }t          |          D ]j}||||z           z  }t          |dz
            D ])}|                    ||||z  |z   dz            z            }*|dk    r|}U|                    |          }k|}t          | d           j
        }	t          ||	          r|S  |	|          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              3   @   K   | ]}t          |t                    V  d S r*   r4   r-   rM   s     r#   r/   z+matrix_kronecker_product.<locals>.<genexpr>.  s,      ;;Qz!Z((;;;;;;r%   z&Sequence of Matrices expected, got: %sNr   r   c                     | j         S r*   )_class_priority)Ms    r#   <lambda>z*matrix_kronecker_product.<locals>.<lambda>J  s	    a.? r%   )key)r8   r   reprrG   r2   rB   rangerow_joincol_joinmaxr?   r5   )
r"   matrix_expansionrD   r2   rB   rI   startrJ   nextMatrixClasss
             r#   matrix_kronecker_productr     sa   Z ;;(;;;;; 
4tH~~E
 
 	

  |"&&    xx t 	, 	,A$S4[0E4!8__  $S4!a%88 
 Av ,}}U++h$?$?@@@JK"K00 -{+,,,r%   c                 ^    t          d | j        D                       s| S t          | j         S )Nc              3   @   K   | ]}t          |t                    V  d S r*   r4   r   s     r#   r/   z-explicit_kronecker_product.<locals>.<genexpr>S  s,      <<Qz!Z((<<<<<<r%   )r8   r=   r   )r   s    r#   explicit_kronecker_productr   Q  s5    <<$)<<<<< #TY//r%   c                 ,    t          | t                    S r*   )r5   r    )xs    r#   r   r   ^  s    :a9I+J+J r%   c                 l    t          | t                    rt          d | j        D                       S dS )Nc              3   $   K   | ]}|j         V  d S r*   rp   r,   s     r#   r/   z&_kronecker_dims_key.<locals>.<genexpr>d  s$      00QW000000r%   r   )r5   r    tupler=   exprs    r#   _kronecker_dims_keyr   b  s9    $()) 00di000000tr%   c                     t          | j        t                    }|                    dd           }|s| S d |                                D             }|s	t          | S t          | |z   S )Nr   c                 0    g | ]}t          d  |          S )c                 ,    |                      |          S r*   )r   )r   ys     r#   r   z.kronecker_mat_add.<locals>.<listcomp>.<lambda>o  s    !1!1!!4!4 r%   r   )r-   groups     r#   rW   z%kronecker_mat_add.<locals>.<listcomp>o  s6     ) ) ) 44e<< ) ) )r%   )r   r=   r   popvaluesr   )r   r=   nonkronskronss       r#   kronecker_mat_addr   i  s}    	.//Dxxd##H ) )++--) ) )E  )u~u~((r%   c                    |                                  \  }}d}|t          |          dz
  k     r|||dz            \  }}t          |t                    rFt          |t                    r1|                    |          ||<   |                    |dz              n|dz  }|t          |          dz
  k     |t          | z  S )Nr   r      )as_coeff_matricesr   r5   r    r   r   r   )r   factorr"   rI   ABs         r#   kronecker_mat_mulr   x  s    --//FH	A
c(mma
 !A#1a)** 	z!=M/N/N 	**1--HQKLL1FA c(mma
  &(###r%   c                      t           j        t                    rBt          d  j        j        D                       rt           fd j        j        D              S  S )Nc              3   $   K   | ]}|j         V  d S r*   rc   r,   s     r#   r/   z$kronecker_mat_pow.<locals>.<genexpr>  s$      6[6[qq{6[6[6[6[6[6[r%   c                 :    g | ]}t          |j                  S rU   )r   exp)r-   r.   r   s     r#   rW   z%kronecker_mat_pow.<locals>.<listcomp>  s%    !N!N!N!&DH"5"5!N!N!Nr%   )r5   baser    r8   r=   r   s   `r#   kronecker_mat_powr     sc    $)-.. 36[6[DIN6[6[6[3[3[ !N!N!N!Nty~!N!N!NOOr%   c                 ,   d }t          t          t          t          |t          t          t
          t          t          t          t          i                                                  } ||           }t          |dd          }|
 |            S |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                 `    t          | t                    o|                     t                    S r*   )r5   r
   hasr    r   s    r#   haskronz"combine_kronecker.<locals>.haskron  s$    $
++J9I0J0JJr%   r!   N)r   r   r   r   r   r   r   r   r   r   getattr)r   r   rulerL   r!   s        r#   combine_kroneckerr     s    .K K K ')GU&&&(.) .) * * + + 	, 	,- -D
 T$ZZF664((D tvvr%   N)4r   	functoolsr   mathr   
sympy.corer   r   sympy.functionsr   sympy.matrices.commonr	   "sympy.matrices.expressions.matexprr
   $sympy.matrices.expressions.transposer   "sympy.matrices.expressions.specialr   sympy.matrices.matricesr   sympy.strategiesr   r   r   r   r   r   r   r   sympy.strategies.traverser   sympy.utilitiesr   mataddr   matmulr   matpowr   r$   r    r   r   r   r   rulesr   r   r   r   r   r   rU   r%   r#   <module>r      s   - -             # # # # # # # # # # # # # # , , , , , , 9 9 9 9 9 9 : : : : : : 7 7 7 7 7 7 . . . . . .K K K K K K K K K K K K K K K K K K K K / / / / / /                              >2 >2 >2BR5 R5 R5 R5 R5z R5 R5 R5j< < <  M- M- M-`0 0 0 
	#			
 wyy!J!J!'1 1 2 2  ) ) )$ $ $   $ $ $ $ $r%   