Skip to content
This repository

Fidelity of quantum states #1459

Merged
merged 8 commits into from over 1 year ago

7 participants

Guru Devanla Don't Add Me To Your Organization a.k.a The Travis Bot Stefan Krastanov Ondřej Čertík Brian E. Granger Sean Vig Aaron Meurer
Guru Devanla

This PR implements the basic functionality to compute fidelity on quantum states.

@flacjacket and @ellisonbg please review.

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request fails (merged 30311c8 into 9625918).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request fails (merged 82e3be2 into 9625918).

Stefan Krastanov
Collaborator

SymPy Bot Summary: :red_circle: There were test failures.

@gdevanla: Please fix the test failures.

Test command: setup.py test
master hash: 9625918
branch hash: 82e3be2

Interpreter 1: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/local/bin/python2.5 (2.5.6-final-0)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sY_ZMjDA

Interpreter 2: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python2.7 (2.7.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYqo8iDA

Interpreter 3: :red_circle: There were test failures.

Interpreter: /usr/bin/python3.2 (3.2.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sY5_QiDA

Build HTML Docs: :eight_spoked_asterisk: All tests have passed.

Docs build command: make html-errors
Sphinx version: 1.1.3

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYju0iDA

Automatic review by SymPy Bot.

sympy/physics/quantum/tests/test_density.py
((44 lines not shown))
  244
+    state4 = (sqrt(S(2)/3))*state1 + (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 fidelity(state1_dm, state3_dm) == 1/sqrt(2)
  253
+    assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
  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 fidelity(d1, d1).round(3) == 1
  259
+    assert fidelity(d1, d2).round(3) == 0.996
2
Ondřej Čertík Owner
certik added a note August 03, 2012

This is wrong. You can't compare floating point numbers like that. You need to do it the following way:

abs(x-y) < 1e-3

Unless there is something that I am missing.

Guru Devanla
gdevanla added a note August 03, 2012

Nope, my mistake. I was supposed to replace that with abs once I finished comparing some of my results with what QuTip was producing. Will fix it, now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/tests/test_density.py
((45 lines not shown))
  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 fidelity(state1_dm, state3_dm) == 1/sqrt(2)
  253
+    assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
  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 fidelity(d1, d1).round(3) == 1
  259
+    assert fidelity(d1, d2).round(3) == 0.996
  260
+    assert fidelity(d1, d2).round(3) == fidelity(d2, d1).round(3)
1
Ondřej Čertík Owner
certik added a note August 03, 2012

The same here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/tests/test_density.py
((43 lines not shown))
  243
+    state3 = (1/sqrt(2))*state1 + (1/sqrt(2))*state2
  244
+    state4 = (sqrt(S(2)/3))*state1 + (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 fidelity(state1_dm, state3_dm) == 1/sqrt(2)
  253
+    assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
  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 fidelity(d1, d1).round(3) == 1
1
Ondřej Čertík Owner
certik added a note August 03, 2012

And the same here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 0eea679 into 9625918).

Stefan Krastanov
Collaborator

SymPy Bot Summary: :eight_spoked_asterisk: All tests have passed.

Test command: setup.py test
master hash: 9625918
branch hash: 0eea679

Interpreter 1: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/local/bin/python2.5 (2.5.6-final-0)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sY_pMjDA

Interpreter 2: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python2.7 (2.7.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sY4_8hDA

Interpreter 3: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python3.2 (3.2.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYj-0iDA

Build HTML Docs: :eight_spoked_asterisk: All tests have passed.

Docs build command: make html-errors
Sphinx version: 1.1.3

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYmowjDA

Automatic review by SymPy Bot.

sympy/physics/quantum/density.py
((16 lines not shown))
  268
+    arg1, arg2 : 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)
1
Ondřej Čertík Owner
certik added a note August 03, 2012

You seem to have an extra space in (amp * up ). (This is minor.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/density.py
((22 lines not shown))
  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
+    >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
4
Ondřej Čertík Owner
certik added a note August 03, 2012

I would format (sqrt(3)/2 )* up as (sqrt(3)/2) * up.

Sean Vig Collaborator

I agree with Ondrej, but you don't ever use updown2

Ondřej Čertík Owner
certik added a note August 10, 2012

@gdevanla, what's up with this? Should updown2 be removed?

Guru Devanla
gdevanla added a note August 10, 2012

@certik I missed that comment in my earlier push. Will address that soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Ondřej Čertík
Owner

Otherwise it looks good. After you fix it, I'll merge it.

sympy/physics/quantum/density.py
@@ -254,3 +253,73 @@ 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(arg1, arg2):
1
Aaron Meurer Owner
asmeurer added a note August 04, 2012

Maybe call these state1 and state2. That way the user can at least guess what the arguments should be from the function signature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/density.py
((33 lines not shown))
  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
+    >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
  290
+    >>>
  291
+    >>> print fidelity(up_dm, up_dm)
  292
+    1
  293
+    >>> print fidelity(up_dm, down_dm) #orthogonal states
  294
+    0
  295
+    >>> print fidelity(up_dm, updown_dm).evalf().round(3)
  296
+    0.707
  297
+
  298
+
  299
+    """
  300
+    def sqrtm(mat):
1
Aaron Meurer Owner
asmeurer added a note August 04, 2012

Matrix**Rational(1, 2) does exactly this already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Brian E. Granger
Owner

One other thing we should add that is fidelity related. By taking the inverse cos of the fidelity you get an angle that is a metric on state space. I am not sure what to call this angle (might need to do some background research on it). A few details can be found on the wikipedia page for quantum fidelity.

Guru Devanla

@ellisonbg I am assuming you are referring to the 'Bures angle/distance', described in here : http://en.wikipedia.org/wiki/Bures_metric.

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request fails (merged ac679d1 into 9625918).

Stefan Krastanov
Collaborator

SymPy Bot Summary: :eight_spoked_asterisk: All tests have passed.

Test command: setup.py test
master hash: 3c2c3c7
branch hash: ac679d1

Interpreter 1: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/local/bin/python2.5 (2.5.6-final-0)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYvd0iDA

Interpreter 2: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python2.7 (2.7.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYv7YiDA

Interpreter 3: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python3.2 (3.2.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYjrMjDA

Build HTML Docs: :eight_spoked_asterisk: All tests have passed.

Docs build command: make html-errors
Sphinx version: 1.1.3

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYm-0iDA

Automatic review by SymPy Bot.

sympy/physics/quantum/density.py
((24 lines not shown))
  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
+    >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
  290
+    >>>
  291
+    >>> print fidelity(up_dm, up_dm)
1
Sean Vig Collaborator

print is unnecessary here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/density.py
((37 lines not shown))
  289
+    >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
  290
+    >>>
  291
+    >>> print fidelity(up_dm, up_dm)
  292
+    1
  293
+    >>> print fidelity(up_dm, down_dm) #orthogonal states
  294
+    0
  295
+    >>> print fidelity(up_dm, updown_dm).evalf().round(3)
  296
+    0.707
  297
+
  298
+    """
  299
+    state1 = represent(state1) if isinstance(state1, Density) else state1
  300
+    state2 = represent(state2) if isinstance(state2, Density) else state2
  301
+
  302
+    if (not isinstance(state1, Matrix) or
  303
+        not isinstance(state2, Matrix)):
  304
+        raise ValueError("state1 and state2 must be of type density or Matrix "
1
Sean Vig Collaborator

Uppercase Density

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sympy/physics/quantum/density.py
((41 lines not shown))
  293
+    >>> print fidelity(up_dm, down_dm) #orthogonal states
  294
+    0
  295
+    >>> print fidelity(up_dm, updown_dm).evalf().round(3)
  296
+    0.707
  297
+
  298
+    """
  299
+    state1 = represent(state1) if isinstance(state1, Density) else state1
  300
+    state2 = represent(state2) if isinstance(state2, Density) else state2
  301
+
  302
+    if (not isinstance(state1, Matrix) or
  303
+        not isinstance(state2, Matrix)):
  304
+        raise ValueError("state1 and state2 must be of type density or Matrix "
  305
+                         "received type=%s for state1 and type=%s for state2" %
  306
+                         (type(state1), type(state2)))
  307
+
  308
+    if ( state1.shape != state2.shape and state1.rows == state2.cols):
1
Sean Vig Collaborator

state1.rows != state2.cols
Though you could also use Matrix.is_square

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sean Vig
Collaborator

This is definitely out of my wheelhouse, but I can at least try to comment on more syntax related improvements.

Stefan Krastanov
Collaborator

SymPy Bot Summary: :eight_spoked_asterisk: All tests have passed.

Test command: setup.py test
master hash: dd8352a
branch hash: 5f0bd5d

Interpreter 1: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/local/bin/python2.5 (2.5.6-final-0)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYi_UiDA

Interpreter 2: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python2.7 (2.7.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYg5wjDA

Interpreter 3: :eight_spoked_asterisk: All tests have passed.

Interpreter: /usr/bin/python3.2 (3.2.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYivUiDA

Build HTML Docs: :eight_spoked_asterisk: All tests have passed.

Docs build command: make html-errors
Sphinx version: 1.1.3

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYyd0iDA

Automatic review by SymPy Bot.

Guru Devanla

I believe I have addressed all comments in this PR. except for the one by @ellisonbg regarding the metric. But that change can go with a follow-up PR and need not be part of this.

Brian E. Granger
Owner

OK I think we can merge this.

Brian E. Granger ellisonbg merged commit 3b77c94 into from August 10, 2012
Brian E. Granger ellisonbg closed this August 10, 2012
Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 02e7e5c into 9625918).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
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))
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.