ó
¡¼™\c           @  sÎ  d  Z  d d l m Z m Z d d l 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 m Z 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) d e f d „  ƒ  YZ* d „  Z+ d „  Z, d „  Z- d „  Z. e e. e e, f Z/ e e d „  e e/ Œ  ƒ ƒ Z0 d „  Z1 d „  Z2 d „  Z3 d „  Z4 d „  Z5 d S(   s'   Implementation of the Kronecker productiÿÿÿÿ(   t   divisiont   print_function(   t   Addt   Mult   Powt   prodt   sympify(   t   range(   t   adjoint(   t
   MatrixExprt
   ShapeErrort   Identity(   t	   transpose(   t
   MatrixBase(   t   canont	   conditiont
   distributet   do_onet   exhaustt   flattent   typedt   unpack(   t	   bottom_up(   t   sifti   (   t   MatAdd(   t   MatMul(   t   MatPowc          G  sM   |  s t  d ƒ ‚ n  t |  Œ  t |  ƒ d k r9 |  d St |  Œ  j ƒ  Sd S(   sf  
    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.matrices 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.matrices 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

    s$   Empty Kronecker product is undefinedi   i    N(   t	   TypeErrort   validatet   lent   KroneckerProductt   doit(   t   matrices(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   kronecker_product   s    8
R   c           B  s¡   e  Z d  Z e Z 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 RS(   sŸ  
    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 the ``.doit()`` or  ``.as_explicit()``
    methods.

    >>> from sympy.matrices import KroneckerProduct, MatrixSymbol
    >>> A = MatrixSymbol('A', 5, 5)
    >>> B = MatrixSymbol('B', 5, 5)
    >>> isinstance(KroneckerProduct(A, B), KroneckerProduct)
    True
    c         O  s¬   t  t t | ƒ ƒ } t d „  | Dƒ ƒ rn t t d „  | Dƒ ƒ ƒ } t d „  | Dƒ ƒ rg | j ƒ  S| Sn  | j d t ƒ } | r“ t	 | Œ  n  t
 t |  ƒ j |  | Œ S(   Nc         s  s   |  ] } | j  Vq d  S(   N(   t   is_Identity(   t   .0t   a(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>m   s    c         s  s   |  ] } | j  Vq d  S(   N(   t   rows(   R#   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>n   s    c         s  s   |  ] } t  | t ƒ Vq d  S(   N(   t
   isinstanceR   (   R#   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>o   s    t   check(   t   listt   mapR   t   allR   R   t   as_explicitt   gett   TrueR   t   superR   t   __new__(   t   clst   argst   kwargst   retR'   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyR/   k   s    
c         C  sR   |  j  d j \ } } x/ |  j  d D]  } | | j 9} | | j 9} q$ W| | f S(   Ni    i   (   R1   t   shapeR%   t   cols(   t   selfR%   R5   t   mat(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyR4   y   s
    c         C  sh   d } x[ t  |  j ƒ D]J } t | | j ƒ \ } } t | | j ƒ \ } } | | | | f 9} q W| S(   Ni   (   t   reversedR1   t   divmodR%   R5   (   R6   t   it   jt   resultR7   t   mt   n(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _entry   s    c         C  s"   t  t t t |  j ƒ ƒ Œ  j ƒ  S(   N(   R   R(   R)   R   R1   R   (   R6   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_adjoint‰   s    c         C  s,   t  g  |  j D] } | j ƒ  ^ q Œ  j ƒ  S(   N(   R   R1   t	   conjugateR   (   R6   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_conjugateŒ   s    c         C  s"   t  t t t |  j ƒ ƒ Œ  j ƒ  S(   N(   R   R(   R)   R   R1   R   (   R6   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_transpose   s    c           s-   d d l  m  ‰  t ‡  f d †  |  j Dƒ ƒ S(   Ni   (   t   tracec         3  s   |  ] } ˆ  | ƒ Vq d  S(   N(    (   R#   R$   (   RD   (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>”   s    (   RD   R   R1   (   R6   (    (   RD   sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_trace’   s    c           sb   d d l  m ‰  m } t d „  |  j Dƒ ƒ s9 | |  ƒ S|  j ‰ t ‡  ‡ f d †  |  j Dƒ ƒ S(   Ni   (   t   dett   Determinantc         s  s   |  ] } | j  Vq d  S(   N(   t	   is_square(   R#   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>˜   s    c         3  s&   |  ] } ˆ  | ƒ ˆ | j  Vq d  S(   N(   R%   (   R#   R$   (   RF   R=   (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>œ   s    (   t   determinantRF   RG   R*   R1   R%   R   (   R6   RG   (    (   RF   R=   sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_determinant–   s
    
	c         C  sY   y* t  g  |  j D] } | j ƒ  ^ q Œ  SWn( t k
 rT d d l m } | |  ƒ SXd  S(   Niÿÿÿÿ(   t   Inverse(   R   R1   t   inverseR
   t"   sympy.matrices.expressions.inverseRK   (   R6   R$   RK   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_inversež   s
    *c         C  sb   t  | t ƒ oa |  j | j k oa t |  j ƒ t | j ƒ k oa t d „  t |  j | j ƒ Dƒ ƒ S(   s‹  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(   N(   R4   (   R#   R$   t   b(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>¼   s    (   R&   R   R4   R   R1   R*   t   zip(   R6   t   other(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   structurally_equal¥   s    c         C  sb   t  | t ƒ oa |  j | j k oa t |  j ƒ t | j ƒ k oa t d „  t |  j | j ƒ Dƒ ƒ S(   sq  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(   N(   R5   R%   (   R#   R$   RO   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>Ò   s    (   R&   R   R5   R%   R   R1   R*   RP   (   R6   RQ   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   has_matching_shape¾   s    c         K  s,   t  t t i t t t ƒ t 6ƒ ƒ |  ƒ ƒ S(   N(   R   R   R   R   R   R   (   R6   t   hints(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _eval_expand_kroneckerproductÔ   s    c         C  sT   |  j  | ƒ rH |  j g  t |  j | j ƒ D] \ } } | | ^ q+ Œ  S|  | Sd  S(   N(   RR   t	   __class__RP   R1   (   R6   RQ   R$   RO   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _kronecker_add×   s    9c         C  sT   |  j  | ƒ rH |  j g  t |  j | j ƒ D] \ } } | | ^ q+ Œ  S|  | Sd  S(   N(   RS   RV   RP   R1   (   R6   RQ   R$   RO   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _kronecker_mulÝ   s    9c         K  sY   | j  d t ƒ } | r@ g  |  j D] } | j |   ^ q" } n	 |  j } t t | Œ  ƒ S(   Nt   deep(   R,   R-   R1   R   t   canonicalizeR   (   R6   R2   RY   t   argR1   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyR   ã   s
    (	(   t   __name__t
   __module__t   __doc__R-   t   is_KroneckerProductR/   t   propertyR4   R?   R@   RB   RC   RE   RJ   RN   RR   RS   RU   RW   RX   R   (    (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyR   V   s"   													c          G  s)   t  d „  |  Dƒ ƒ s% t d ƒ ‚ n  d  S(   Nc         s  s   |  ] } | j  Vq d  S(   N(   t	   is_Matrix(   R#   R[   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>í   s    s    Mix of Matrix and Scalar symbols(   R*   R   (   R1   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyR   ì   s    c         C  s   g  } g  } xF |  j  D]; } | j ƒ  \ } } | j | ƒ | j t j | ƒ ƒ q Wt | Œ  } | d k r{ | t | Œ  S|  S(   Ni   (   R1   t   args_cnct   extendt   appendR   t
   _from_argsR   (   t   kront   c_partt   nc_partR[   t   ct   nc(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   extract_commutativeó   s    c    
      G  s0  t  d „  |  Dƒ ƒ s/ t d t |  ƒ ƒ ‚ n  |  d } x» t |  d  ƒ D]© } | j } | j } xˆ t | ƒ D]z } | | | | } x; t | d ƒ D]) } | j | | | | | d ƒ } q˜ W| d k rÚ | } qo | j | ƒ } qo W| } qJ Wt	 |  d d „  ƒj
 }	 t | |	 ƒ r"| S|	 | ƒ Sd S(	   s“  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(   N(   R&   R   (   R#   R=   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>.  s    s&   Sequence of Matrices expected, got: %siÿÿÿÿi   i    t   keyc         S  s   |  j  S(   N(   t   _class_priority(   t   M(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   <lambda>J  t    N(   R*   R   t   reprR8   R%   R5   R   t   row_joint   col_joint   maxRV   R&   (
   R    t   matrix_expansionR7   R%   R5   R:   t   startR;   t   nextt   MatrixClass(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   matrix_kronecker_product  s(    -
		!	
c         C  s*   t  d „  |  j Dƒ ƒ s |  St |  j Œ  S(   Nc         s  s   |  ] } t  | t ƒ Vq d  S(   N(   R&   R   (   R#   R=   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>S  s    (   R*   R1   Ry   (   Rf   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   explicit_kronecker_productQ  s    c         C  s   t  |  t ƒ S(   N(   R&   R   (   t   x(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyRo   ^  Rp   c         C  s.   t  |  t ƒ r& t d „  |  j Dƒ ƒ Sd Sd  S(   Nc         s  s   |  ] } | j  Vq d  S(   N(   R4   (   R#   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pys	   <genexpr>d  s    i    (   i    (   R&   R   t   tupleR1   (   t   expr(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   _kronecker_dims_keyb  s    c         C  s‹   d d l  m } t |  j t ƒ } | j d d  ƒ } | s> |  Sg  | j ƒ  D] } | d „  | ƒ ^ qK } | sy t | Œ  St | Œ  | Sd  S(   Niÿÿÿÿ(   t   reducei    c         S  s   |  j  | ƒ S(   N(   RW   (   R{   t   y(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyRo   p  Rp   (   i    (	   t	   functoolsR   R   R1   R~   t   popt   Nonet   valuesR   (   R}   R   R1   t   nonkronst   groupt   krons(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   kronecker_mat_addi  s    (
c         C  s©   |  j  ƒ  \ } } d } x€ | t | ƒ d k  rš | | | d !\ } } t | t ƒ r t | t ƒ r | j | ƒ | | <| j | d ƒ q | d 7} q W| t | Œ  S(   Ni    i   i   (   t   as_coeff_matricesR   R&   R   RX   R‚   R   (   R}   t   factorR    R:   t   At   B(    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   kronecker_mat_muly  s    c         C  sI   t  |  j t ƒ rA t g  |  j j D] } t | |  j ƒ ^ q" Œ  S|  Sd  S(   N(   R&   t   baseR   R1   R   t   exp(   R}   R$   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   kronecker_mat_pow‰  s    /c      	   C  s~   d „  } t  t t  t | t i t t 6t t 6t t	 6ƒ ƒ ƒ ƒ ƒ } | |  ƒ } t
 | d d ƒ } | d k	 rv | ƒ  S| Sd S(   så  Combine KronekeckerProduct with expression.

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

    Examples
    ========

    >>> from sympy.matrices.expressions import MatrixSymbol, KroneckerProduct, combine_kronecker
    >>> from sympy import 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)
    >>> combine_kronecker(KroneckerProduct(A, B)**m)
    KroneckerProduct(A**m, B**m)
    c         S  s   t  |  t ƒ o |  j t ƒ S(   N(   R&   R	   t   hasR   (   R}   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   haskron¥  s    R   N(   R   R   R   R   Rˆ   R   R   R   R   R   t   getattrRƒ   (   R}   R’   t   ruleR<   R   (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   combine_kronecker  s    	
N(6   R^   t
   __future__R    R   t
   sympy.coreR   R   R   R   R   t   sympy.core.compatibilityR   t   sympy.functionsR   t"   sympy.matrices.expressions.matexprR	   R
   R   t$   sympy.matrices.expressions.transposeR   t   sympy.matrices.matricesR   t   sympy.strategiesR   R   R   R   R   R   R   R   t   sympy.strategies.traverseR   t   sympy.utilitiesR   t   mataddR   t   matmulR   t   matpowR   R!   R   R   Rk   Ry   Rz   t   rulesRZ   R~   Rˆ   R   R   R•   (    (    (    sC   lib/python2.7/site-packages/sympy/matrices/expressions/kronecker.pyt   <module>   s<   (:	A–			P						