
    Цi&                         S SK Jr  S SKJr  S SKJr  S SKJr  S SKJ	r	  S SK
Jr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  S SKJrJrJr  S SKJrJr  S SK J!r!   " S S\5      r"S r#S r$g)    )product)Add)Tuple)expand)Mul)Slog)MutableDenseMatrix
prettyForm)Dagger)HermitianOperator)	represent)numpy_ndarrayscipy_sparse_matrixto_numpy)TensorProducttensor_product_simp)Trc                   ~   ^  \ rS rSrSr\U 4S j5       rS rS rS r	S r
S rS	 rS
 rS rS rS rS rS rSrU =r$ )Density   a  Density operator for representing mixed states.

TODO: Density operator support for Qubits

Parameters
==========

values : tuples/lists
Each tuple/list should be of form (state, prob) or [state,prob]

Examples
========

Create a density operator with 2 states represented by Kets.

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d
Density((|0>, 0.5),(|1>, 0.5))

c                    > [         TU ]  U5      nU H2  n[        U[        5      (       a  [	        U5      S:X  a  M)  [        S5      e   U$ )N   z?Each argument should be of form [state,prob] or ( state, prob ))super
_eval_args
isinstancer   len
ValueError)clsargsarg	__class__s      \/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/sympy/physics/quantum/density.pyr   Density._eval_args*   sN     w!$'CsE**s3x1}  "7 8 8      c                 V    [        U R                   Vs/ s H  oS   PM	     sn6 $ s  snf )zReturn list of all states.

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.states()
(|0>, |1>)

r   r   r"   selfr#   s     r%   statesDensity.states7   '     3#1v3443   &c                 V    [        U R                   Vs/ s H  oS   PM	     sn6 $ s  snf )zReturn list of all probabilities.

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.probs()
(0.5, 0.5)

   r)   r*   s     r%   probsDensity.probsF   r.   r/   c                 *    U R                   U   S   nU$ )a  Return specific state by index.

Parameters
==========

index : index of state to be returned

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.states()[1]
|1>

r   r"   )r+   indexstates      r%   	get_stateDensity.get_stateU   s    $ 		% #r'   c                 *    U R                   U   S   nU$ )aJ  Return probability of specific state by index.

Parameters
===========

index : index of states whose probability is returned.

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.probs()[1]
0.500000000000000

r1   r5   )r+   r6   probs      r%   get_probDensity.get_probj   s    $ yy"r'   c                 f    U R                    VVs/ s H  u  p#X-  U4PM     nnn[        U6 $ s  snnf )a{  op will operate on each individual state.

Parameters
==========

op : Operator

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> from sympy.physics.quantum.operator import Operator
>>> A = Operator('A')
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.apply_op(A)
Density((A*|0>, 0.5),(A*|1>, 0.5))

)r"   r   )r+   opr7   r;   new_argss        r%   apply_opDensity.apply_op   s6    ( ;?))D)%RXt$)D!! Es   -c           
      Z   / nU R                    H  u  p4UR                  5       n[        U[        5      (       aF  [	        UR                   SS9 H,  nUR                  X@R                  US   US   5      -  5        M.     Mp  UR                  X@R                  X35      -  5        M     [        U6 $ )aU  Expand the density operator into an outer product format.

Examples
========

>>> from sympy.physics.quantum.state import Ket
>>> from sympy.physics.quantum.density import Density
>>> from sympy.physics.quantum.operator import Operator
>>> A = Operator('A')
>>> d = Density([Ket(0), 0.5], [Ket(1),0.5])
>>> d.doit()
0.5*|0><0| + 0.5*|1><1|

r   )repeatr   r1   )r"   r   r   r   r   append_generate_outer_prod)r+   hintstermsr7   r;   r#   s         r%   doitDensity.doit   s      !YYMULLNE5#&&"5::a8CLL&?&?A@CA'H "H I 9 T";";E"IIJ ' E{r'   c                    UR                  5       u  p4UR                  5       u  pV[        U5      S:X  d  [        U5      S:X  a  [        S5      e[        US   [        5      (       a<  [        U5      S:X  a-  [        U5      S:X  a  [        US   [        US   5      -  5      nO[        U6 [        [        U6 5      -  n[        U6 [        U6 -  U-  $ )Nr   zHAtleast one-pair of Non-commutative instance required for outer product.r1   )args_cncr   r    r   r   r   r   r   )r+   arg1arg2c_part1nc_part1c_part2nc_part2r?   s           r%   rF   Density._generate_outer_prod   s     MMO MMOMQ#h-1"4 3 4 4 x{M22s8}7IMQ&$Xa[1D%DEBhsH~ 66BG}S']*R//r'   c                 6    [        U R                  5       40 UD6$ N)r   rI   )r+   optionss     r%   
_representDensity._represent   s    000r'   c                     g)Nz\rho r+   printerr"   s      r%   _print_operator_name_latex"Density._print_operator_name_latex   s    r'   c                     [        S5      $ )Nu   ρr   r[   s      r%   _print_operator_name_pretty#Density._print_operator_name_pretty   s    677r'   c                 v    UR                  S/ 5      n[        U R                  5       U5      R                  5       $ )Nindices)getr   rI   )r+   kwargsrc   s      r%   _eval_traceDensity._eval_trace   s.    **Y+$))+w',,..r'   c                     [        U 5      $ )z[Compute the entropy of a density matrix.

Refer to density.entropy() method  for examples.
)entropy)r+   s    r%   ri   Density.entropy   s    
 t}r'   rZ   )__name__
__module____qualname____firstlineno____doc__classmethodr   r,   r2   r8   r<   rA   rI   rF   rW   r]   r`   rf   ri   __static_attributes____classcell__)r$   s   @r%   r   r      s]    , 
 
55**".80&18/ r'   r   c                    [        U [        5      (       a  [        U 5      n [        U [        5      (       a  [	        U 5      n [        U [
        5      (       a:  U R                  5       R                  5       n[        [        S U 5       5      * 5      $ [        U [        5      (       aB  SSKnUR                  R                  U 5      nUR                  XR                  U5      -  5      * $ [        S5      e)a{  Compute the entropy of a matrix/density object.

This computes -Tr(density*ln(density)) using the eigenvalue decomposition
of density, which is given as either a Density instance or a matrix
(numpy.ndarray, sympy.Matrix or scipy.sparse).

Parameters
==========

density : density matrix of type Density, SymPy matrix,
scipy.sparse or numpy.ndarray

Examples
========

>>> from sympy.physics.quantum.density import Density, entropy
>>> from sympy.physics.quantum.spin import JzKet
>>> from sympy import S
>>> up = JzKet(S(1)/2,S(1)/2)
>>> down = JzKet(S(1)/2,-S(1)/2)
>>> d = Density((up,S(1)/2),(down,S(1)/2))
>>> entropy(d)
log(2)/2

c              3   <   #    U  H  o[        U5      -  v   M     g 7frU   r	   ).0es     r%   	<genexpr>entropy.<locals>.<genexpr>   s     5WSV8Ws   r   Nz4numpy.ndarray, scipy.sparse or SymPy matrix expected)r   r   r   r   r   Matrix	eigenvalskeysr   sumr   numpylinalgeigvalsr
   r    )densityr   nps      r%   ri   ri      s    4 '7##G$'.//7#'6""##%**,s5W55566	G]	+	+))##G,wvvg.///BD 	Dr'   c                    [        U [        5      (       a  [        U 5      OU n [        U[        5      (       a  [        U5      OUn[        U [        5      (       a  [        U[        5      (       d&  [	        S[        U 5      < S[        U5      < S35      eU R                  UR                  :w  a  U R                  (       a  [	        S5      eU [        R                  -  n[        X!-  U-  [        R                  -  5      R                  5       $ )a#  Computes the fidelity [1]_ between two quantum states

The arguments provided to this function should be a square matrix or a
Density object. If it is a square matrix, it is assumed to be diagonalizable.

Parameters
==========

state1, state2 : a density matrix or Matrix


Examples
========

>>> from sympy import S, sqrt
>>> from sympy.physics.quantum.dagger import Dagger
>>> from sympy.physics.quantum.spin import JzKet
>>> from sympy.physics.quantum.density import fidelity
>>> from sympy.physics.quantum.represent import represent
>>>
>>> up = JzKet(S(1)/2,S(1)/2)
>>> down = JzKet(S(1)/2,-S(1)/2)
>>> amp = 1/sqrt(2)
>>> updown = (amp*up) + (amp*down)
>>>
>>> # represent turns Kets into matrices
>>> up_dm = represent(up*Dagger(up))
>>> down_dm = represent(down*Dagger(down))
>>> updown_dm = represent(updown*Dagger(updown))
>>>
>>> fidelity(up_dm, up_dm)
1
>>> fidelity(up_dm, down_dm) #orthogonal states
0
>>> fidelity(up_dm, updown_dm).evalf().round(3)
0.707

References
==========

.. [1] https://en.wikipedia.org/wiki/Fidelity_of_quantum_states

zBstate1 and state2 must be of type Density or Matrix received type=z for state1 and type=z for state2z]The dimensions of both args should be equal and the matrix obtained should be a square matrix)r   r   r   ry   r    typeshape	is_squarer   Halfr   rI   )state1state2sqrt_state1s      r%   fidelityr     s    X #-VW"="=Yv6F",VW"="=Yv6Fff%%Z-G-Gv,V6 7 	7 ||v||#(8(8 E F 	F !&&.K{!+-67<<>>r'   N)%	itertoolsr   sympy.core.addr   sympy.core.containersr   sympy.core.functionr   sympy.core.mulr   sympy.core.singletonr   &sympy.functions.elementary.exponentialr
   sympy.matrices.denser   ry    sympy.printing.pretty.stringpictr   sympy.physics.quantum.daggerr   sympy.physics.quantum.operatorr   sympy.physics.quantum.representr   !sympy.physics.quantum.matrixutilsr   r   r   #sympy.physics.quantum.tensorproductr   r   sympy.physics.quantum.tracer   r   ri   r   rZ   r'   r%   <module>r      sQ      ' &  " 6 = 7 / < 5 Z Z R *D DN)DX9?r'   