
    sg\4                     `   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 Z3y) 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                  n    | st        d      t        |       dk(  r| d   S t        |  j                         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    W/var/www/html/venv/lib/python3.12/site-packages/sympy/matrices/expressions/kronecker.pykronecker_productr"      s>    p >??
8}{*//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                   t        t        t        |            }t        d |D              r?t	        t        d |D                    }t        d |D              r|j                         S |S |rt        |  t        | $  | g| S )Nc              3   4   K   | ]  }|j                     y wN)is_Identity.0as     r!   	<genexpr>z+KroneckerProduct.__new__.<locals>.<genexpr>m   s     +q}}+   c              3   4   K   | ]  }|j                     y wr(   )rowsr*   s     r!   r-   z+KroneckerProduct.__new__.<locals>.<genexpr>n   s     515r.   c              3   <   K   | ]  }t        |t                y wr(   
isinstancer   r*   s     r!   r-   z+KroneckerProduct.__new__.<locals>.<genexpr>o   s     ;:a,;   )
listmapr   allr   r   as_explicitvalidatesuper__new__)clsr%   argsret	__class__s       r!   r;   zKroneckerProduct.__new__k   su    C&'+d++45556C;d;;((
dOws*T**r#   c                     | j                   d   j                  \  }}| j                   dd  D ]   }||j                  z  }||j                  z  }" ||fS )Nr   r   )r=   shaper0   cols)selfr0   rB   mats       r!   rA   zKroneckerProduct.shapex   sZ    YYq\''
d99QR= 	CCHHDCHHD	 d|r#   c                     d}t        | j                        D ]>  }t        ||j                        \  }}t        ||j                        \  }}||||f   z  }@ |S Nr   )reversedr=   divmodr0   rB   )rC   ijkwargsresultrD   mns           r!   _entryzKroneckerProduct._entry   s`    DII& 	 C!SXX&DAq!SXX&DAqc!Q$iF	  r#   c                 p    t        t        t        t        | j                               j                         S r(   )r   r5   r6   r   r=   r   rC   s    r!   _eval_adjointzKroneckerProduct._eval_adjoint   s&    c'499&=!>?DDFFr#   c                     t        | j                  D cg c]  }|j                          c} j                         S c c}w r(   )r   r=   	conjugater   )rC   r,   s     r!   _eval_conjugatez KroneckerProduct._eval_conjugate   s.    !CA!++-!CDIIKK!Cs   =c                 p    t        t        t        t        | j                               j                         S r(   )r   r5   r6   r
   r=   r   rQ   s    r!   _eval_transposez KroneckerProduct._eval_transpose   s&    c)TYY&?!@AFFHHr#   c                 d    ddl m } t        | j                  D cg c]
  } ||       c} S c c}w )Nr   )trace)rY   r   r=   )rC   rY   r,   s      r!   _eval_tracezKroneckerProduct._eval_trace   s&     tyy1!U1X1221s   -c                     ddl m}m} t        d | j                  D              s ||       S | j
                  }t        | j                  D cg c]  } ||      ||j
                  z  z   c} S c c}w )Nr   )detDeterminantc              3   4   K   | ]  }|j                     y wr(   	is_squarer*   s     r!   r-   z5KroneckerProduct._eval_determinant.<locals>.<genexpr>   s     211;;2r.   )determinantr\   r]   r7   r=   r0   r   )rC   r\   r]   rM   r,   s        r!   _eval_determinantz"KroneckerProduct._eval_determinant   sY    12		22t$$II;ASVah';<<;s   A/c                     	 t        | j                  D cg c]  }|j                          c} S c c}w # t        $ r ddlm}  ||       cY S w xY w)Nr   )Inverse)r   r=   inverser   "sympy.matrices.expressions.inverserd   )rC   r,   rd   s      r!   _eval_inversezKroneckerProduct._eval_inverse   sF    	!#499%Eaaiik%EFF%E 	!B4= 	!s   5 05 5 AAc                    t        |t              xrx | j                  |j                  k(  xr] t        | j                        t        |j                        k(  xr0 t        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   T   K   | ]   \  }}|j                   |j                   k(   " y wr(   rA   r+   r,   bs      r!   r-   z6KroneckerProduct.structurally_equal.<locals>.<genexpr>   s!     Tv1177*T   &()r3   r   rA   r   r=   r7   ziprC   others     r!   structurally_equalz#KroneckerProduct.structurally_equal   sn    ( 5"23 UJJ%++-U		Nc%**o5U TTYY

9STT	Vr#   c                    t        |t              xrx | j                  |j                  k(  xr] t	        | j
                        t	        |j
                        k(  xr0 t        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   T   K   | ]   \  }}|j                   |j                  k(   " y wr(   )rB   r0   rk   s      r!   r-   z6KroneckerProduct.has_matching_shape.<locals>.<genexpr>   s!     RVa!&&(Rrm   )r3   r   rB   r0   r   r=   r7   rn   ro   s     r!   has_matching_shapez#KroneckerProduct.has_matching_shape   sn    " 5"23 SII+S		Nc%**o5S Rs499ejj7QRR	Tr#   c                 x    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$4jAQSY6Z#[\]^bcddr#   c                     | j                  |      rC | j                  t        | j                  |j                        D cg c]
  \  }}||z    c}} S | |z   S c c}}w r(   )rq   r?   rn   r=   rC   rp   r,   rl   s       r!   _kronecker_addzKroneckerProduct._kronecker_add   sS    ""5)!4>>DIIuzz8R#Sfq!AE#STT%< $T   A
c                     | j                  |      rC | j                  t        | j                  |j                        D cg c]
  \  }}||z   c}} S | |z  S c c}}w r(   )rt   r?   rn   r=   ry   s       r!   _kronecker_mulzKroneckerProduct._kronecker_mul   sS    ""5)!4>>c$))UZZ6P#QFQAaC#QRR%< $Rr{   c                     |j                  dd      }|r*| j                  D cg c]  } |j                  di | }}n| j                  }t        t	        |       S c c}w )NdeepT )getr=   r   canonicalizer   )rC   rv   r   argr=   s        r!   r   zKroneckerProduct.doit   sY    yy&15;#HCHH%u%;D;99D,d344 <s   A)__name__
__module____qualname____doc__is_KroneckerProductr;   propertyrA   rO   rR   rU   rW   rZ   rb   rg   rq   rt   rw   rz   r}   r   __classcell__)r?   s   @r!   r   r   V   ss    $ "& +  GLI3=!V2T,e  5r#   r   c                  >    t        d | D              st        d      y )Nc              3   4   K   | ]  }|j                     y w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 ]J  }|j                         \  }}|j                  |       |j                  t	        j
                  |             L t	        | }|dk7  r|t        | z  S | S rF   )r=   args_cncextendappendr   
_from_argsr   )kronc_partnc_partr   cncs         r!   extract_commutativer      sw    FGyy +2as~~b)*+
 &\F{&000Kr#   c            	         t        d | D              st        dt        |       z        | d   }t        | dd       D ]  }|j                  }|j
                  }t        |      D ]Y  }||||z     z  }t        |dz
        D ]"  }|j                  ||||z  |z   dz      z        }$ |dk(  r|}Ij                  |      }[ } 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                y wr(   r2   r+   rM   s     r!   r-   z+matrix_kronecker_product.<locals>.<genexpr>-  s     ;Qz!Z(;r4   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   r0   rB   rangerow_joincol_joinmaxr?   r3   )
r    matrix_expansionrD   r0   rB   rI   startrJ   nextMatrixClasss
             r!   matrix_kronecker_productr      s   Z ;(;;4tH~E
 	

  |"&  xxxx t 	,A$S4[0E4!8_ $S4!a%88 Av}}U+	,  % ( h$?@JJK"K0+,,r#   c                 b    t        d | j                  D              s| S t        | j                   S )Nc              3   <   K   | ]  }t        |t                y wr(   r2   r   s     r!   r-   z-explicit_kronecker_product.<locals>.<genexpr>R  s     <Qz!Z(<r4   )r7   r=   r   )r   s    r!   explicit_kronecker_productr   P  s(    <$))<<#TYY//r#   c                 "    t        | t              S r(   )r3   r   )xs    r!   r   r   ]  s    :a9I+J r#   c                 \    t        | t              rt        d | j                  D              S y)Nc              3   4   K   | ]  }|j                     y wr(   rj   r*   s     r!   r-   z&_kronecker_dims_key.<locals>.<genexpr>c  s     0QWW0r.   r   )r3   r   tupler=   exprs    r!   _kronecker_dims_keyr   a  s%    $()0dii000r#   c                     t        | j                  t              }|j                  dd       }|s| S |j	                         D cg c]  }t        d |       }}|st        | S t        | |z   S c c}w )Nr   c                 $    | j                  |      S r(   )rz   )r   ys     r!   r   z#kronecker_mat_add.<locals>.<lambda>n  s    !1!1!!4 r#   )r   r=   r   popvaluesr   r   )r   r=   nonkronsgroupkronss        r!   kronecker_mat_addr   h  s{    		./Dxxd#H ++-) 4e< )E ) u~u~(()s   A.c                 :   | j                         \  }}d}|t        |      dz
  k  rk|||dz    \  }}t        |t              r9t        |t              r)|j	                  |      ||<   |j                  |dz          n|dz  }|t        |      dz
  k  rk|t        | z  S )Nr   r      )as_coeff_matricesr   r3   r   r}   r   r   )r   factorr    rI   ABs         r!   kronecker_mat_mulr   w  s    --/FH	A
c(ma
!A#1a)*z!=M/N**1-HQKLL1FA c(ma
 &(###r#   c           	         t        | j                  t              rdt        d | j                  j                  D              r>t        | j                  j                  D cg c]  }t        || j                         c} S | S c c}w )Nc              3   4   K   | ]  }|j                     y wr(   r_   r*   s     r!   r-   z$kronecker_mat_pow.<locals>.<genexpr>  s     6[qq{{6[r.   )r3   baser   r7   r=   r   exp)r   r,   s     r!   kronecker_mat_powr     sZ    $))-.36[DIINN6[3[tyy~~!N!&DHH"5!NOO "Os   B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                 P    t        | t              xr | j                  t              S r(   )r3   r	   hasr   r   s    r!   haskronz"combine_kronecker.<locals>.haskron  s    $
+J9I0JJr#   r   N)r   r   r   r   r   r   r   r   r   r   getattr)r   r   rulerL   r   s        r!   combine_kroneckerr     su    .K ')GU&&&(.) * + 	,-D
 $ZF664(Dv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   r   r#   r!   <module>r      s    -   # # 0 9 : 7 0K K K /     =2@R5z R5j<M-`0 
	#			
 y!J!'1 2)$ $r#   