
    sg:                        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 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)DenseMatrix)ImmutableDenseMatrix)
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    V/var/www/html/venv/lib/python3.12/site-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        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MatrixImmutableMatrixr   r   r   flattenr   r   lenr   __new__)clsargsc_partnew_argstps        r   r%   zTensorProduct.__new__{   s    d1g4G I J($//;;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)r7   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)r7   printerr'   lengthsr8   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   .0r3   s     r   	<genexpr>z(TensorProduct._pretty.<locals>.<genexpr>        ?cZS)?   c              3   <   K   | ]  }t        |t                y wr,   r    r   rN   s     r   rP   z(TensorProduct._pretty.<locals>.<genexpr>   rQ   rR   rA   r   , {})leftrightr   rB   rC   u   ⨂ zx )r   allr'   r$   rF   rE   r
   rY   parensrX   lbracketrbracketr    r   r   _use_unicode)
r7   rG   r'   rH   pformr8   
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,   rM   rN   s     r   rP   z'TensorProduct._latex.<locals>.<genexpr>   rQ   rR   c              3   <   K   | ]  }t        |t                y wr,   rT   rN   s     r   rP   z'TensorProduct._latex.<locals>.<genexpr>   rQ   rR   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   rU   rV   r   rW   rA   z\left(z\right)r   z\otimes )r   rZ   r'   join_print_label_latexr$   lbracket_latexrbracket_latexrE   r    r   r   rF   )r7   rG   r'   rl   r3   rI   rH   r8   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 )Nri   )r   r'   doit)r7   r>   items      r   rs   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'   rE   r$   r    r   r   r-   _eval_expand_tensorproductr0   r   )	r7   r>   r'   add_argsr8   aar*   r(   nc_parts	            r   rv   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   rs   	enumerate)r7   kwargsr{   expr3   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#   r9   r?   rJ   rd   rq   rs   rv   r   ri   r   r   r   r   5   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   rE   tensor_product_simp_Mul)er(   ry   n_nccurrentn_termsr)   nextr8   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   o  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>   r3   s      r   r   r   y  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.matrices.immutabler	   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   ri   r   r   <module>r      s|           & 6 L 7 4 / 7 ? 0 
 +   " [AD [A|Zx0r   