
    \hJ%                         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   " 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)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      U/var/www/auris/envauris/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.states6   '     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.probsE   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_stateT   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

r/   r3   )r)   r4   probs      r#   get_probDensity.get_probi   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)   opr5   r9   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   r/   )r    r   r   r   r   append_generate_outer_prod)r)   hintstermsr5   r9   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6 [	        [        U6 5      -  n[        U6 [        U6 -  U-  $ )Nr   zHAtleast one-pair of Non-commutative instance required for outer product.)args_cncr   r   r   r   )r)   arg1arg2c_part1nc_part1c_part2nc_part2r=   s           r#   rD   Density._generate_outer_prod   sx     MMO MMOMQ#h-1"4 3 4 4 (^F3>22G}S']*R//r%   c                 6    [        U R                  5       40 UD6$ N)r   rG   )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   rY   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   rG   )r)   kwargsra   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#   rg   Density.entropy   s    
 t}r%   rX   )__name__
__module____qualname____firstlineno____doc__classmethodr   r*   r0   r6   r:   r?   rG   rD   rU   r[   r^   rd   rg   __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rS   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#   rg   rg      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   rw   r   typeshape	is_squarer   Halfr   rG   )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   rw    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.tracer   r   rg   r   rX   r%   r#   <module>r      sN      ' &  " 6 = 7 / < 5 Z Z *A AH)DX9?r%   