Skip to content
This repository
Browse code

Merge pull request #1459 from gdevanla/fidelity_quantum_states

Fidelity of quantum states
  • Loading branch information...
commit 3b77c9446cdd3d60cc26dcb4ed553bc51e4db9c8 2 parents 0336f70 + 02e7e5c
Brian E. Granger ellisonbg authored
142 examples/notebooks/fidelity.ipynb
... ... @@ -0,0 +1,142 @@
  1 +{
  2 + "metadata": {
  3 + "name": "fidelity"
  4 + },
  5 + "nbformat": 2,
  6 + "worksheets": [
  7 + {
  8 + "cells": [
  9 + {
  10 + "cell_type": "code",
  11 + "collapsed": false,
  12 + "input": [
  13 + "from sympy import *",
  14 + "from sympy.physics.quantum import *",
  15 + "from sympy.physics.quantum.density import *",
  16 + "from sympy.physics.quantum.spin import (",
  17 + " Jx, Jy, Jz, Jplus, Jminus, J2,",
  18 + " JxBra, JyBra, JzBra,",
  19 + " JxKet, JyKet, JzKet,",
  20 + ")",
  21 + "from IPython.core.display import display_pretty",
  22 + "from sympy.physics.quantum.operator import *",
  23 + "",
  24 + "%load_ext sympyprinting"
  25 + ],
  26 + "language": "python",
  27 + "outputs": [],
  28 + "prompt_number": 2
  29 + },
  30 + {
  31 + "cell_type": "markdown",
  32 + "source": [
  33 + "##Fidelity using some kets"
  34 + ]
  35 + },
  36 + {
  37 + "cell_type": "code",
  38 + "collapsed": false,
  39 + "input": [
  40 + "up = JzKet(S(1)/2,S(1)/2)",
  41 + "down = JzKet(S(1)/2,-S(1)/2)",
  42 + "amp = 1/sqrt(2)",
  43 + "updown = (amp * up ) + (amp * down)",
  44 + "",
  45 + "# represent turns Kets into matrices",
  46 + "up_dm = represent(up * Dagger(up))",
  47 + "down_dm = represent(down * Dagger(down)) ",
  48 + "updown_dm = represent(updown * Dagger(updown))",
  49 + "updown2 = (sqrt(3)/2 )* up + (1/2)*down",
  50 + "",
  51 + "",
  52 + "display_pretty(fidelity(up_dm, up_dm))",
  53 + "display_pretty(fidelity(up_dm, down_dm)) #orthogonal states",
  54 + "display_pretty(fidelity(up_dm, updown_dm).evalf())",
  55 + "",
  56 + "",
  57 + "# alternatively, puts Kets into Density object and compute fidelity",
  58 + "d1 = Density( [updown, 0.25], [updown2, 0.75])",
  59 + "d2 = Density( [updown, 0.75], [updown2, 0.25])",
  60 + "display_pretty(fidelity(d1, d2))"
  61 + ],
  62 + "language": "python",
  63 + "outputs": [
  64 + {
  65 + "output_type": "display_data",
  66 + "text": [
  67 + "1"
  68 + ]
  69 + },
  70 + {
  71 + "output_type": "display_data",
  72 + "text": [
  73 + "0"
  74 + ]
  75 + },
  76 + {
  77 + "output_type": "display_data",
  78 + "text": [
  79 + "0.707106781186548"
  80 + ]
  81 + },
  82 + {
  83 + "output_type": "display_data",
  84 + "text": [
  85 + "0.817293551913876"
  86 + ]
  87 + }
  88 + ],
  89 + "prompt_number": 7
  90 + },
  91 + {
  92 + "cell_type": "markdown",
  93 + "source": [
  94 + "## Fidelity on states as Qubits"
  95 + ]
  96 + },
  97 + {
  98 + "cell_type": "code",
  99 + "collapsed": false,
  100 + "input": [
  101 + "",
  102 + "from sympy.physics.quantum.qubit import Qubit",
  103 + "state1 = Qubit('0')",
  104 + "state2 = Qubit('1')",
  105 + "state3 = (1/sqrt(2))*state1 + (1/sqrt(2))*state2",
  106 + "state4 = (sqrt(S(2)/3))*state1 + (1/sqrt(3))*state2",
  107 + "",
  108 + "state1_dm = Density([state1, 1])",
  109 + "state2_dm = Density([state2, 1])",
  110 + "state3_dm = Density([state3, 1])",
  111 + "",
  112 + "# mixed qubit states in density",
  113 + "d1 = Density([state3, 0.70], [state4, 0.30])",
  114 + "d2 = Density([state3, 0.20], [state4, 0.80])",
  115 + "",
  116 + "",
  117 + "display_pretty(fidelity(d1, d2))",
  118 + "",
  119 + ""
  120 + ],
  121 + "language": "python",
  122 + "outputs": [
  123 + {
  124 + "output_type": "display_data",
  125 + "text": [
  126 + "0.996370452558227"
  127 + ]
  128 + }
  129 + ],
  130 + "prompt_number": 9
  131 + },
  132 + {
  133 + "cell_type": "code",
  134 + "collapsed": true,
  135 + "input": [],
  136 + "language": "python",
  137 + "outputs": []
  138 + }
  139 + ]
  140 + }
  141 + ]
  142 +}
60 sympy/physics/quantum/density.py
... ... @@ -1,10 +1,9 @@
1   -from sympy import Tuple, Add, Mul, Matrix, log, expand
  1 +from sympy import Tuple, Add, Mul, Matrix, log, expand, sqrt, Rational
2 2 from sympy.core.trace import Tr
3 3 from sympy.printing.pretty.stringpict import prettyForm
4 4 from sympy.physics.quantum.dagger import Dagger
5 5 from sympy.physics.quantum.operator import HermitianOperator, OuterProduct, Operator
6 6 from sympy.physics.quantum.represent import represent
7   -from sympy.physics.quantum.state import KetBase
8 7 from matrixutils import numpy_ndarray, scipy_sparse_matrix, to_numpy
9 8 from sympy.physics.quantum.tensorproduct import TensorProduct, tensor_product_simp
10 9 from sympy.core.compatibility import product
@@ -254,3 +253,60 @@ def entropy(density):
254 253 return -np.sum(eigvals*np.log(eigvals))
255 254 else:
256 255 raise ValueError("numpy.ndarray, scipy.sparse or sympy matrix expected")
  256 +
  257 +
  258 +def fidelity(state1, state2):
  259 + """ Computes the fidelity between two quantum states
  260 + (http://en.wikipedia.org/wiki/Fidelity_of_quantum_states)
  261 +
  262 + The arguments provided to this function should be a square matrix or a
  263 + Density object. If it is a square matrix, it is assumed to be diagonalizable.
  264 +
  265 + Parameters:
  266 + ==========
  267 +
  268 + state1, state2 : a density matrix or Matrix
  269 +
  270 +
  271 + Examples:
  272 + =========
  273 +
  274 + >>> from sympy import S, sqrt
  275 + >>> from sympy.physics.quantum.dagger import Dagger
  276 + >>> from sympy.physics.quantum.spin import JzKet
  277 + >>> from sympy.physics.quantum.density import Density, fidelity
  278 + >>> from sympy.physics.quantum.represent import represent
  279 + >>>
  280 + >>> up = JzKet(S(1)/2,S(1)/2)
  281 + >>> down = JzKet(S(1)/2,-S(1)/2)
  282 + >>> amp = 1/sqrt(2)
  283 + >>> updown = (amp * up) + (amp * down)
  284 + >>>
  285 + >>> # represent turns Kets into matrices
  286 + >>> up_dm = represent(up * Dagger(up))
  287 + >>> down_dm = represent(down * Dagger(down))
  288 + >>> updown_dm = represent(updown * Dagger(updown))
  289 + >>>
  290 + >>> fidelity(up_dm, up_dm)
  291 + 1
  292 + >>> fidelity(up_dm, down_dm) #orthogonal states
  293 + 0
  294 + >>> fidelity(up_dm, updown_dm).evalf().round(3)
  295 + 0.707
  296 +
  297 + """
  298 + state1 = represent(state1) if isinstance(state1, Density) else state1
  299 + state2 = represent(state2) if isinstance(state2, Density) else state2
  300 +
  301 + if (not isinstance(state1, Matrix) or
  302 + not isinstance(state2, Matrix)):
  303 + raise ValueError("state1 and state2 must be of type Density or Matrix "
  304 + "received type=%s for state1 and type=%s for state2" %
  305 + (type(state1), type(state2)))
  306 +
  307 + if ( state1.shape != state2.shape and state1.is_square):
  308 + raise ValueError("The dimensions of both args should be equal and the"
  309 + "matrix obtained should be a square matrix")
  310 +
  311 + sqrt_state1 = state1**Rational(1,2)
  312 + return Tr((sqrt_state1 * state2 * sqrt_state1)**Rational(1, 2)).doit()
81 sympy/physics/quantum/tests/test_density.py
@@ -2,7 +2,7 @@
2 2 from sympy.matrices.matrices import Matrix
3 3 from sympy.core.trace import Tr
4 4 from sympy.external import import_module
5   -from sympy.physics.quantum.density import Density, entropy
  5 +from sympy.physics.quantum.density import Density, entropy, fidelity
6 6 from sympy.physics.quantum.state import Ket, Bra, TimeDepKet
7 7 from sympy.physics.quantum.qubit import Qubit
8 8 from sympy.physics.quantum.qapply import qapply
@@ -201,3 +201,82 @@ def _eval_trace(self, bra, **options):
201 201
202 202 t = Tr(d)
203 203 assert t.doit() == 1
  204 +
  205 +
  206 +def test_fidelity():
  207 + #test with kets
  208 + up = JzKet(S(1)/2, S(1)/2)
  209 + down = JzKet(S(1)/2, -S(1)/2)
  210 + updown = (S(1)/sqrt(2))*up + (S(1)/sqrt(2))*down
  211 +
  212 + #check with matrices
  213 + up_dm = represent(up * Dagger(up))
  214 + down_dm = represent(down * Dagger(down))
  215 + updown_dm = represent(updown * Dagger(updown))
  216 +
  217 + assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
  218 + assert fidelity(up_dm, down_dm) < 1e-3
  219 + assert abs(fidelity(up_dm, updown_dm) - (S(1)/sqrt(2))) < 1e-3
  220 + assert abs(fidelity(updown_dm, down_dm) - (S(1)/sqrt(2))) < 1e-3
  221 +
  222 + #check with density
  223 + up_dm = Density([up, 1.0])
  224 + down_dm = Density([down, 1.0])
  225 + updown_dm = Density([updown, 1.0])
  226 +
  227 + assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
  228 + assert abs(fidelity(up_dm, down_dm)) < 1e-3
  229 + assert abs(fidelity(up_dm, updown_dm) - (S(1)/sqrt(2))) < 1e-3
  230 + assert abs(fidelity(updown_dm, down_dm) - (S(1)/sqrt(2))) < 1e-3
  231 +
  232 + #check mixed states with density
  233 + updown2 = (sqrt(3)/2)*up + (S(1)/2)*down
  234 + d1 = Density([updown, 0.25], [updown2, 0.75])
  235 + d2 = Density([updown, 0.75], [updown2, 0.25])
  236 + assert abs(fidelity(d1, d2) - 0.991) < 1e-3
  237 + assert abs(fidelity(d2, d1) - fidelity(d1, d2)) < 1e-3
  238 +
  239 +
  240 + #using qubits/density(pure states)
  241 + state1 = Qubit('0')
  242 + state2 = Qubit('1')
  243 + state3 = (S(1)/sqrt(2))*state1 + (S(1)/sqrt(2))*state2
  244 + state4 = (sqrt(S(2)/3))*state1 + (S(1)/sqrt(3))*state2
  245 +
  246 + state1_dm = Density([state1, 1])
  247 + state2_dm = Density([state2, 1])
  248 + state3_dm = Density([state3, 1])
  249 +
  250 + assert fidelity(state1_dm, state1_dm) == 1
  251 + assert fidelity(state1_dm, state2_dm) == 0
  252 + assert abs(fidelity(state1_dm, state3_dm) - 1/sqrt(2)) < 1e-3
  253 + assert abs(fidelity(state3_dm, state2_dm) - 1/sqrt(2)) < 1e-3
  254 +
  255 + #using qubits/density(mixed states)
  256 + d1 = Density([state3, 0.70], [state4, 0.30])
  257 + d2 = Density([state3, 0.20], [state4, 0.80])
  258 + assert abs(fidelity(d1, d1) - 1) < 1e-3
  259 + assert abs(fidelity(d1, d2) - 0.996) < 1e-3
  260 + assert abs(fidelity(d1, d2) - fidelity(d2, d1)) < 1e-3
  261 +
  262 + #TODO: test for invalid arguments
  263 + # non-square matrix
  264 + mat1 = [[0, 0],
  265 + [0, 0],
  266 + [0, 0]]
  267 +
  268 + mat2 = [[0, 0],
  269 + [0, 0]]
  270 + raises(ValueError, lambda: fidelity(mat1, mat2))
  271 +
  272 + # unequal dimensions
  273 + mat1 = [[0, 0],
  274 + [0, 0]]
  275 + mat2 = [[0, 0, 0],
  276 + [0, 0, 0],
  277 + [0, 0, 0]]
  278 + raises(ValueError, lambda: fidelity(mat1, mat2))
  279 +
  280 + # unsupported data-type
  281 + x, y = 1, 2 #random values that is not a matrix
  282 + raises(ValueError, lambda: fidelity(x, y))

0 comments on commit 3b77c94

Please sign in to comment.
Something went wrong with that request. Please try again.