
    g\4                     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          |           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lenKroneckerProductdoit)matricess    `/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/matrices/expressions/kronecker.pykronecker_productr#      sO    p  @>???
8}}{*//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>m   s$      ++q}++++++r$   c              3   $   K   | ]}|j         V  d S r)   rowsr+   s     r"   r.   z+KroneckerProduct.__new__.<locals>.<genexpr>n   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>o   s,      ;;:a,,;;;;;;r$   )
listmapr   allr   r   as_explicitvalidatesuper__new__)clsr&   argsret	__class__s       r"   r;   zKroneckerProduct.__new__k   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=   shaper1   cols)selfr1   rB   mats       r"   rA   zKroneckerProduct.shapex   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=   divmodr1   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   r5   r6   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   r5   r6   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   r0   )r,   r-   r`   rM   s     r"   rW   z6KroneckerProduct._eval_determinant.<locals>.<listcomp>   s,    ;;;ASSVVah';;;r$   )determinantr`   ra   r7   r=   r1   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$   )r4   r   rA   r   r=   r7   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   r1   rq   s      r"   r.   z6KroneckerProduct.has_matching_shape.<locals>.<genexpr>   s/      RRVa!&(RRRRRRr$   )r4   r   rB   r1   r   r=   r7   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   V   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)r7   r   )r=   s    r"   r9   r9      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{{&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)   r3   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>I  s	    a.? r$   )key)r7   r   reprrG   r1   rB   rangerow_joincol_joinmaxr?   r4   )
r!   matrix_expansionrD   r1   rB   rI   startrJ   nextMatrixClasss
             r"   matrix_kronecker_productr      s^   Z ;;(;;;;; 
4tH~~E
 
 	

  |"&&    xx t 	, 	,A$S4[0E4!8__  $S4!a%88 
 Avv}}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)   r3   r   s     r"   r.   z-explicit_kronecker_product.<locals>.<genexpr>R  s,      <<Qz!Z((<<<<<<r$   )r7   r=   r   )r   s    r"   explicit_kronecker_productr   P  s5    <<$)<<<<< #TY//r$   c                 ,    t          | t                    S r)   )r4   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>c  s$      00QW000000r$   r   )r4   r   tupler=   exprs    r"   _kronecker_dims_keyr   a  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>n  s    !1!1!!4!4 r$   r   )r,   groups     r"   rW   z%kronecker_mat_add.<locals>.<listcomp>n  s6     ) ) ) 44e<< ) ) )r$   )r   r=   r   popvaluesr   )r   r=   nonkronskronss       r"   kronecker_mat_addr   h  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   r4   r   r   r   r   )r   factorr!   rI   ABs         r"   kronecker_mat_mulr   w  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$   )r4   baser   r7   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)   )r4   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.exceptionsr	   "sympy.matrices.expressions.matexprr
   $sympy.matrices.expressions.transposer   "sympy.matrices.expressions.specialr   sympy.matrices.matrixbaser   sympy.strategiesr   r   r   r   r   r   r   r   sympy.strategies.traverser   sympy.utilitiesr   mataddr   matmulr   matpowr   r#   r   r9   r   r   r   rulesr   r   r   r   r   r   rU   r$   r"   <module>r      s   - -             # # # # # # # # # # # # # # 0 0 0 0 0 0 9 9 9 9 9 9 : : : : : : 7 7 7 7 7 7 0 0 0 0 0 0K K K K K K K K K K K K K K K K K K K K / / / / / /                              =2 =2 =2@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$   