# Density operator and matrix



In [59]:

from sympy import *
from sympy.physics.quantum import *
from sympy.physics.quantum.density import *
from sympy.physics.quantum.spin import (
Jx, Jy, Jz, Jplus, Jminus, J2,
JxBra, JyBra, JzBra,
JxKet, JyKet, JzKet,
)
from IPython.core.display import display_pretty




In [60]:



Create n density matrix using symbolic states



In [61]:

psi = Ket('psi')
phi = Ket('phi')




In [62]:

d = Density((psi,0.5),(phi,0.5)); d




Out[62]:

$$\rho\left(\begin{pmatrix}{\left|\psi\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}{\left|\phi\right\rangle }, & 0.5\end{pmatrix}\right)$$




In [63]:

display_pretty(d)




ρ((❘ψ⟩, 0.5),(❘φ⟩, 0.5))




In [64]:

d.states()




Out[64]:

$$\begin{pmatrix}{\left|\psi\right\rangle }, & {\left|\phi\right\rangle }\end{pmatrix}$$




In [65]:

d.probs()




Out[65]:

$$\begin{pmatrix}0.5, & 0.5\end{pmatrix}$$




In [66]:

d.doit()




Out[66]:

$$0.5 {\left|\phi\right\rangle }{\left\langle \phi\right|} + 0.5 {\left|\psi\right\rangle }{\left\langle \psi\right|}$$




In [67]:

Dagger(d)




Out[67]:

$$\rho\left(\begin{pmatrix}{\left|\psi\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}{\left|\phi\right\rangle }, & 0.5\end{pmatrix}\right)$$




In [68]:

A = Operator('A')




In [69]:

d.apply_op(A)




Out[69]:

$$\rho\left(\begin{pmatrix}A {\left|\psi\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}A {\left|\phi\right\rangle }, & 0.5\end{pmatrix}\right)$$



Now create a density matrix using spin states



In [70]:

up = JzKet(S(1)/2,S(1)/2)
down = JzKet(S(1)/2,-S(1)/2)




In [71]:

d2 = Density((up,0.5),(down,0.5)); d2




Out[71]:

$$\rho\left(\begin{pmatrix}{\left|\frac{1}{2},\frac{1}{2}\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}{\left|\frac{1}{2},- \frac{1}{2}\right\rangle }, & 0.5\end{pmatrix}\right)$$




In [72]:

represent(d2)




Out[72]:

$$\left[\begin{smallmatrix}0.5 & 0\\0 & 0.5\end{smallmatrix}\right]$$




In [73]:

d2.apply_op(Jz)




Out[73]:

$$\rho\left(\begin{pmatrix}J_z {\left|\frac{1}{2},\frac{1}{2}\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}J_z {\left|\frac{1}{2},- \frac{1}{2}\right\rangle }, & 0.5\end{pmatrix}\right)$$




In [74]:

qapply(_)




Out[74]:

$$\rho\left(\begin{pmatrix}\frac{1}{2} \hbar {\left|\frac{1}{2},\frac{1}{2}\right\rangle }, & 0.5\end{pmatrix},\begin{pmatrix}- \frac{1}{2} \hbar {\left|\frac{1}{2},- \frac{1}{2}\right\rangle }, & 0.5\end{pmatrix}\right)$$




In [75]:

qapply((Jy*d2).doit())




Out[75]:

$$0.5 J_y {\left|\frac{1}{2},- \frac{1}{2}\right\rangle }{\left\langle \frac{1}{2},- \frac{1}{2}\right|} + 0.5 J_y {\left|\frac{1}{2},\frac{1}{2}\right\rangle }{\left\langle \frac{1}{2},\frac{1}{2}\right|}$$



## Evaluate entropy of the density matrices



In [76]:

entropy(d2)




Out[76]:

$$\frac{1}{2} \log{\left (2 \right )}$$




In [77]:

entropy(represent(d2))




Out[77]:

$$\frac{1}{2} \log{\left (2 \right )}$$




In [78]:

entropy(represent(d2,format="numpy"))




Out[78]:

(0.69314718056-0j)




In [79]:

entropy(represent(d2,format="scipy.sparse"))




Out[79]:

(0.69314718056-0j)



## Density operators with Tensor Products as args



In [80]:

from sympy.core.trace import Tr

A, B, C, D = symbols('A B C D',commutative=False)

t1 = TensorProduct(A,B,C)

d = Density([t1, 1.0])
d.doit()

t2 = TensorProduct(A,B)
t3 = TensorProduct(C,D)

d = Density([t2, 0.5], [t3, 0.5])
d.doit()




Out[80]:

$$0.5 \left({A A^{\dagger}}\right)\otimes \left({B B^{\dagger}}\right) + 0.5 \left({C C^{\dagger}}\right)\otimes \left({D D^{\dagger}}\right)$$




In [81]:

#mixed states
d = Density([t2+t3, 1.0])
d.doit()




Out[81]:

$$1.0 \left({A A^{\dagger}}\right)\otimes \left({B B^{\dagger}}\right) + 1.0 \left({A C^{\dagger}}\right)\otimes \left({B D^{\dagger}}\right) + 1.0 \left({C A^{\dagger}}\right)\otimes \left({D B^{\dagger}}\right) + 1.0 \left({C C^{\dagger}}\right)\otimes \left({D D^{\dagger}}\right)$$



## Trace operators on Density Operators with Spin States



In [82]:

from sympy.physics.quantum.density import Density
from sympy.physics.quantum.spin import (
Jx, Jy, Jz, Jplus, Jminus, J2,
JxBra, JyBra, JzBra,
JxKet, JyKet, JzKet,
)
from sympy.core.trace import Tr

d = Density([JzKet(1,1),0.5],[JzKet(1,-1),0.5]);
t = Tr(d);

display_pretty(t)
print t.doit()




Tr(ρ((❘1,1⟩, 0.5),(❘1,-1⟩, 0.5)))

1.00000000000000



## Partial Trace on Density Operators with Mixed State



In [83]:

#Partial trace on mixed state
from sympy.core.trace import Tr

A, B, C, D = symbols('A B C D',commutative=False)

t1 = TensorProduct(A,B,C)

d = Density([t1, 1.0])
d.doit()

t2 = TensorProduct(A,B)
t3 = TensorProduct(C,D)

d = Density([t2, 0.5], [t3, 0.5])

tr = Tr(d,[1])
tr.doit()




Out[83]:

$$0.5 A A^{\dagger} \mbox{Tr}\left(B B^{\dagger}\right) + 0.5 C C^{\dagger} \mbox{Tr}\left(D D^{\dagger}\right)$$



## Partial Trace on Density Operators with Spin states



In [84]:

from sympy.physics.quantum.density import Density
from sympy.physics.quantum.spin import (
Jx, Jy, Jz, Jplus, Jminus, J2,
JxBra, JyBra, JzBra,
JxKet, JyKet, JzKet,
)
from sympy.core.trace import Tr

tp1 = TensorProduct(JzKet(1,1), JzKet(1,-1))

#trace out 0 index
d = Density([tp1,1]);
t = Tr(d,[0]);

display_pretty(t)
display_pretty(t.doit())

#trace out 1 index
t = Tr(d,[1])
display_pretty(t)
t.doit()




Tr((❘1,1⟩⨂ ❘1,-1⟩, 1))

❘1,-1⟩⟨1,-1❘

Tr((❘1,1⟩⨂ ❘1,-1⟩, 1))

Out[84]:

$${\left|1,1\right\rangle }{\left\langle 1,1\right|}$$



## Examples of qapply() on Density matrices with spin states



In [85]:

psi = Ket('psi')
phi = Ket('phi')

u = UnitaryOperator()
d = Density((psi,0.5),(phi,0.5)); d

display_pretty(qapply(u*d))

# another example
up = JzKet(S(1)/2, S(1)/2)
down = JzKet(S(1)/2, -S(1)/2)
d = Density((up,0.5),(down,0.5))

uMat = Matrix([[0,1],[1,0]])
display_pretty(qapply(uMat*d))




ρ((O⋅❘ψ⟩, 0.5),(O⋅❘φ⟩, 0.5))

⎡                  0                    ρ((❘1/2,1/2⟩, 0.5),(❘1/2,-1/2⟩, 0.5))⎤
⎢                                                                            ⎥
⎣ρ((❘1/2,1/2⟩, 0.5),(❘1/2,-1/2⟩, 0.5))                    0                  ⎦



## Example of qapply() on Density Matrices with qubits



In [90]:

from sympy.physics.quantum.gate import UGate
from sympy.physics.quantum.qubit import Qubit

uMat = UGate((0,), Matrix([[0,1],[1,0]]))
d = Density([Qubit('0'),0.5],[Qubit('1'), 0.5])

display_pretty(d)

#after applying Not gate
display_pretty(qapply(uMat*d) )




ρ((❘0⟩, 0.5),(❘1⟩, 0.5))

ρ((❘1⟩, 0.5),(❘0⟩, 0.5))




In [86]: