
    MZdp:                         d 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 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 ddlmZmZmZ ddlm Z  ddgZ!da"d Z# G d de      Z$d Z%d Z&d Z'y)zAbstract tensor product.    )Add)Expr)Mul)Pow)sympify)MutableDenseMatrix)
prettyForm)QuantumError)Dagger)
Commutator)AntiCommutator)KetBra)numpy_ndarrayscipy_sparse_matrixmatrix_tensor_product)TrTensorProducttensor_product_simpFc                     | a y)a  Set flag controlling whether tensor products of states should be
    printed as a combined bra/ket or as an explicit tensor product of different
    bra/kets. This is a global setting for all TensorProduct class instances.

    Parameters
    ----------
    combine : bool
        When true, tensor product states are combined into one ket/bra, and
        when false explicit tensor product notation is used between each
        ket/bra.
    N)_combined_printing)combineds    E/usr/lib/python3/dist-packages/sympy/physics/quantum/tensorproduct.pycombined_tensor_printingr   $   s
     "    c                   Z    e Zd ZdZdZd Zed        Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zy)r   a  The tensor product of two or more arguments.

    For matrices, this uses ``matrix_tensor_product`` to compute the Kronecker
    or tensor product matrix. For other objects a symbolic ``TensorProduct``
    instance is returned. The tensor product is a non-commutative
    multiplication that is used primarily with operators and states in quantum
    mechanics.

    Currently, the tensor product distinguishes between commutative and
    non-commutative arguments.  Commutative arguments are assumed to be scalars
    and are pulled out in front of the ``TensorProduct``. Non-commutative
    arguments remain in the resulting ``TensorProduct``.

    Parameters
    ==========

    args : tuple
        A sequence of the objects to take the tensor product of.

    Examples
    ========

    Start with a simple tensor product of SymPy matrices::

        >>> from sympy import Matrix
        >>> from sympy.physics.quantum import TensorProduct

        >>> m1 = Matrix([[1,2],[3,4]])
        >>> m2 = Matrix([[1,0],[0,1]])
        >>> TensorProduct(m1, m2)
        Matrix([
        [1, 0, 2, 0],
        [0, 1, 0, 2],
        [3, 0, 4, 0],
        [0, 3, 0, 4]])
        >>> TensorProduct(m2, m1)
        Matrix([
        [1, 2, 0, 0],
        [3, 4, 0, 0],
        [0, 0, 1, 2],
        [0, 0, 3, 4]])

    We can also construct tensor products of non-commutative symbols:

        >>> from sympy import Symbol
        >>> A = Symbol('A',commutative=False)
        >>> B = Symbol('B',commutative=False)
        >>> tp = TensorProduct(A, B)
        >>> tp
        AxB

    We can take the dagger of a tensor product (note the order does NOT reverse
    like the dagger of a normal product):

        >>> from sympy.physics.quantum import Dagger
        >>> Dagger(tp)
        Dagger(A)xDagger(B)

    Expand can be used to distribute a tensor product across addition:

        >>> C = Symbol('C',commutative=False)
        >>> tp = TensorProduct(A+B,C)
        >>> tp
        (A + B)xC
        >>> tp.expand(tensorproduct=True)
        AxC + BxC
    Fc                    t        |d   t        t        t        f      rt	        | S | j                  t        |            \  }}t        | }t        |      dk(  r|S t        |      dk(  r||d   z  S t        j                  | g| }||z  S )Nr      )
isinstanceMatrixr   r   r   flattenr   r   lenr   __new__)clsargsc_partnew_argstps        r   r#   zTensorProduct.__new__z   s    d1g7JKL($//;;wt}5fx=AM]aHQK''c-H-BB;r   c                     g }g }|D ]S  }|j                         \  }}|j                  t        |             |j                  t	        j
                  |             U ||fS N)args_cncextendlistappendr   
_from_args)r$   r%   r&   nc_partsargcpncps          r   r!   zTensorProduct.flatten   s^      	1CllnGBMM$r(#OOCNN3/0	1 xr   c                 ^    t        | j                  D cg c]  }t        |       c} S c c}w r*   )r   r%   r   )selfis     r   _eval_adjointzTensorProduct._eval_adjoint   s#    $))<Qvay<==<s   *c                 2    t        | j                  d      S )NT)tensorproduct)r   expand)r5   ruler%   hintss       r   _eval_rewritezTensorProduct._eval_rewrite   s    d#***>>r   c                 f   t        | j                        }d}t        |      D ]  }t        | j                  |   t        t
        t        f      r|dz   }||j                  | j                  |         z   }t        | j                  |   t        t
        t        f      r|dz   }||dz
  k7  s|dz   } |S )N ()r   x)r"   r%   ranger   r   r   r   _print)r5   printerr%   lengthsr6   s         r   	_sympystrzTensorProduct._sympystr   s    TYYv 	A$))A,c38GGNN499Q<00A$))A,c38GFQJG	 r   c                    t         rt        d | j                  D              st        d | j                  D              rt        | j                        } |j                  dg| }t        |      D ]"  } |j                  dg| }t        | j                  |   j                        }t        |      D ]f  } |j                  | j                  |   j                  |   g| }	t        |j                  |	       }||dz
  k7  sPt        |j                  d       }h t        | j                  |   j                        dkD  rt        |j                  dd       }t        |j                  |       }||dz
  k7  st        |j                  d       }% t        |j                  | j                  d	   j                         }t        |j                  | j                  d	   j                         }|S t        | j                        } |j                  dg| }t        |      D ]  } |j                  | j                  |   g| }t        | j                  |   t        t        f      rt        |j                  d
d       }t        |j                  |       }||dz
  k7  s|j                  rt        |j                  d       }t        |j                  d       } |S )Nc              3   <   K   | ]  }t        |t                y wr*   r   r   .0r1   s     r   	<genexpr>z(TensorProduct._pretty.<locals>.<genexpr>        ?cZS)?   c              3   <   K   | ]  }t        |t                y wr*   r   r   rL   s     r   rN   z(TensorProduct._pretty.<locals>.<genexpr>   rO   rP   r?   r   , {})leftrightr   r@   rA   u   ⨂ zx )r   allr%   r"   rD   rC   r	   rW   parensrV   lbracketrbracketr   r   r   _use_unicode)
r5   rE   r%   rF   pformr6   
next_pformlength_ij
part_pforms
             r   _prettyzTensorProduct._pretty   s   ?TYY???TYY??^F"GNN2--E6] @+W^^B66
tyy|001x IA!/		!0A0A!0D!Lt!LJ!+Z-=-=j-I!JJHqL(%/1A1A$1G%H
	I tyy|(()A-!+#**3*?"AJ"EKK
$;<
?&I(>?E@  

499Q<+@+@ ABEDIIaL,A,A BCELTYYr)D)v 	@A'		!<t<J$))A,c
3'&&Cs&;
 J 78EFQJ''&4\(]^E&I(>?E	@ r   c                    t         rt        d | j                  D              st        d | j                  D              rd }dj                  | j                  D cg c]/  } | |j                  |g| t        |j                              1 c}      }d| j                  d   j                  || j                  d   j                  dS t        | j                        }d}t        |      D ]  }t        | j                  |   t        t        f      r|d	z   }|dz    |j                  | j                  |   g| z   dz   }t        | j                  |   t        t        f      r|d
z   }||dz
  k7  s|dz   } |S c c}w )Nc              3   <   K   | ]  }t        |t                y wr*   rK   rL   s     r   rN   z'TensorProduct._latex.<locals>.<genexpr>   rO   rP   c              3   <   K   | ]  }t        |t                y wr*   rR   rL   s     r   rN   z'TensorProduct._latex.<locals>.<genexpr>   rO   rP   c                     |dk(  r| S d| z  S )Nr   z\left\{%s\right\} )labelnlabelss     r   _label_wrapz)TensorProduct._latex.<locals>._label_wrap   s     '1uN2F2NNr   rS   rT   r   rU   r?   z\left(z\right)r   z\otimes )r   rX   r%   join_print_label_latexr"   lbracket_latexrbracket_latexrC   r   r   r   rD   )r5   rE   r%   rj   r1   rG   rF   r6   s           r   _latexzTensorProduct._latex   sd   ?TYY???TYY??O 

BF))M;> ((>(>(>w(N(N(+CHH7 M NA #'))A,"="=q"&))A,"="=? ? TYYv 		$A$))A,c
3	M C.'..1===CA$))A,c
3
NFQJO		$ %Ms   4E>c           
      l    t        | j                  D cg c]  } |j                  di | c} S c c}w )Nrg   )r   r%   doit)r5   r<   items      r   rq   zTensorProduct.doit   s-    diiHdytyy151HIIHs   1c                    | j                   }g }t        t        |            D ]  }t        ||   t              s||   j                   D ]  }t        |d| |fz   ||dz   d z    }|j                         \  }}t        |      dk(  r't        |d   t
              r|d   j                         f}|j                  t        | t        | z           n |rt	        | S | S )z*Distribute TensorProducts across addition.Nr   r   )
r%   rC   r"   r   r   r   r+   _eval_expand_tensorproductr.   r   )	r5   r<   r%   add_argsr6   aar(   r&   nc_parts	            r   rt   z(TensorProduct._eval_expand_tensorproduct   s    yys4y! 
	A$q'3'q',, @B&RaB5(84A<(GHB&(kkmOFG 7|q(Z
M-R#*1:#H#H#J"MOOCLg$>?@ 
	 >!Kr   c           	      v   |j                  dd       }t        |       }|t        |      dk(  r7t        |j                  D cg c]  }t        |      j                          c} S t        t        |j                        D cg c]$  \  }}||v rt        |      j                         n|& c}} S c c}w c c}}w )Nindicesr   )getr   r"   r   r%   r   rq   	enumerate)r5   kwargsry   expr1   idxvalues          r   _eval_tracezTensorProduct._eval_trace  s    **Y-!$'?c'la/388<CC<==+4SXX+>@'S% .1G^E)F @ A A =@s    B0)B5
N)__name__
__module____qualname____doc__is_commutativer#   classmethodr!   r7   r=   rH   rb   ro   rq   rt   r   rg   r   r   r   r   4   sT    BF N    >?*X:J*Ar   c                    t        | t              s| S | j                         \  }}t        |      }|dk(  r| S |dk(  r,t        |d   t              rt        | t        |d         z  S | S | j                  t              r|d   }t        |t              sDt        |t              r&t        |j                  t              rt        |      }nt        d|z        t        |j                        }t        |j                        }|dd D ]  }t        |t              r[|t        |j                        k7  rt        d|d|      t        t        |            D ]  }||   |j                  |   z  ||<    nt        |t              ret        |j                  t              r=t        |      }	t        t        |            D ]  }||   |	j                  |   z  ||<    nt        d|z        t        d|z        |} t        | t        | z  S | j                  t              r2|D 
cg c]  }
t        |
       }}
t        t        | t        | z        S | S c c}
w )at  Simplify a Mul with TensorProducts.

    Current the main use of this is to simplify a ``Mul`` of ``TensorProduct``s
    to a ``TensorProduct`` of ``Muls``. It currently only works for relatively
    simple cases where the initial ``Mul`` only has scalars and raw
    ``TensorProduct``s, not ``Add``, ``Pow``, ``Commutator``s of
    ``TensorProduct``s.

    Parameters
    ==========

    e : Expr
        A ``Mul`` of ``TensorProduct``s to be simplified.

    Returns
    =======

    e : Expr
        A ``TensorProduct`` of ``Mul``s.

    Examples
    ========

    This is an example of the type of simplification that this function
    performs::

        >>> from sympy.physics.quantum.tensorproduct import                     tensor_product_simp_Mul, TensorProduct
        >>> from sympy import Symbol
        >>> A = Symbol('A',commutative=False)
        >>> B = Symbol('B',commutative=False)
        >>> C = Symbol('C',commutative=False)
        >>> D = Symbol('D',commutative=False)
        >>> e = TensorProduct(A,B)*TensorProduct(C,D)
        >>> e
        AxB*CxD
        >>> tensor_product_simp_Mul(e)
        (A*C)x(B*D)

    r   r   zTensorProduct expected, got: %rNz%TensorProducts of different lengths: z and )r   r   r+   r"   r   tensor_product_simp_Powhasr   base	TypeErrorr%   r-   r
   rC   tensor_product_simp_Mul)er&   rw   n_nccurrentn_termsr'   nextr6   new_tpncs              r   r   r     s2   X ajjlOFGw<Dqy	gaj#&L#:71:#FFF	
}	!*'=1'3'gllM:5g>G AG KLLgll#%ABK 	D$.c$))n,& $(  s8}- =A"*1+		!"<HQK= dC(!$))];!8!>!&s8}!5 GA*21+A*FHQKG ((ID(PQQ#$E$LMMG)	* F|mX666	
s;BDR,R0DD&sF|mX6N'NOO Es   &Ic                     t        | t              s| S t        | j                  t              r7t        | j                  j                  D cg c]  }|| j
                  z   c} S | S c c}w )z=Evaluates ``Pow`` expressions whose base is ``TensorProduct``)r   r   r   r   r%   r}   )r   bs     r   r   r   m  sO    a!&&-(!&&++>Q155>?? ?s   
A&c                 ^   t        | t              r)t        | j                  D cg c]  }t        |       c} S t        | t              rGt        | j
                  t              rt        |       S t        | j
                        | j                  z  S t        | t              rt        |       S t        | t              r)t        | j                  D cg c]  }t        |       c} S t        | t              r)t        | j                  D cg c]  }t        |       c} S | S c c}w c c}w c c}w )a3  Try to simplify and combine TensorProducts.

    In general this will try to pull expressions inside of ``TensorProducts``.
    It currently only works for relatively simple cases where the products have
    only scalars, raw ``TensorProducts``, not ``Add``, ``Pow``, ``Commutators``
    of ``TensorProducts``. It is best to see what it does by showing examples.

    Examples
    ========

    >>> from sympy.physics.quantum import tensor_product_simp
    >>> from sympy.physics.quantum import TensorProduct
    >>> from sympy import Symbol
    >>> A = Symbol('A',commutative=False)
    >>> B = Symbol('B',commutative=False)
    >>> C = Symbol('C',commutative=False)
    >>> D = Symbol('D',commutative=False)

    First see what happens to products of tensor products:

    >>> e = TensorProduct(A,B)*TensorProduct(C,D)
    >>> e
    AxB*CxD
    >>> tensor_product_simp(e)
    (A*C)x(B*D)

    This is the core logic of this function, and it works inside, powers, sums,
    commutators and anticommutators as well:

    >>> tensor_product_simp(e**2)
    (A*C)x(B*D)**2

    )r   r   r%   r   r   r   r   r   r}   r   r   r   r   )r   r<   r1   s      r   r   r   w  s    D !S@#(-@AA	As	affm,*1--&qvv.!%%77	As	&q))	Az	"G/4GHH	A~	&AFFKS 3C 8KLL A HKs   D D%D*N)(r   sympy.core.addr   sympy.core.exprr   sympy.core.mulr   sympy.core.powerr   sympy.core.sympifyr   sympy.matrices.denser   r     sympy.printing.pretty.stringpictr	   sympy.physics.quantum.qexprr
   sympy.physics.quantum.daggerr    sympy.physics.quantum.commutatorr   $sympy.physics.quantum.anticommutatorr   sympy.physics.quantum.stater   r   !sympy.physics.quantum.matrixutilsr   r   r   sympy.physics.quantum.tracer   __all__r   r   r   r   r   r   rg   r   r   <module>r      sy           & = 7 4 / 7 ? 0 
 +   " ZAD ZAzZx0r   