Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fidelity of quantum states #1459

Merged
merged 8 commits into from

7 participants

@gdevanla

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

@flacjacket and @ellisonbg please review.

@travisbot

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

@travisbot

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

@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))
+ state4 = (sqrt(S(2)/3))*state1 + (1/sqrt(3))*state2
+
+ state1_dm = Density([state1, 1])
+ state2_dm = Density([state2, 1])
+ state3_dm = Density([state3, 1])
+
+ assert fidelity(state1_dm, state1_dm) == 1
+ assert fidelity(state1_dm, state2_dm) == 0
+ assert fidelity(state1_dm, state3_dm) == 1/sqrt(2)
+ assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
+
+ #using qubits/density(mixed states)
+ d1 = Density([state3, 0.70], [state4, 0.30])
+ d2 = Density([state3, 0.20], [state4, 0.80])
+ assert fidelity(d1, d1).round(3) == 1
+ assert fidelity(d1, d2).round(3) == 0.996
@certik Owner
certik added a note

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.

@gdevanla
gdevanla added a note

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))
+
+ state1_dm = Density([state1, 1])
+ state2_dm = Density([state2, 1])
+ state3_dm = Density([state3, 1])
+
+ assert fidelity(state1_dm, state1_dm) == 1
+ assert fidelity(state1_dm, state2_dm) == 0
+ assert fidelity(state1_dm, state3_dm) == 1/sqrt(2)
+ assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
+
+ #using qubits/density(mixed states)
+ d1 = Density([state3, 0.70], [state4, 0.30])
+ d2 = Density([state3, 0.20], [state4, 0.80])
+ assert fidelity(d1, d1).round(3) == 1
+ assert fidelity(d1, d2).round(3) == 0.996
+ assert fidelity(d1, d2).round(3) == fidelity(d2, d1).round(3)
@certik Owner
certik added a note

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))
+ state3 = (1/sqrt(2))*state1 + (1/sqrt(2))*state2
+ state4 = (sqrt(S(2)/3))*state1 + (1/sqrt(3))*state2
+
+ state1_dm = Density([state1, 1])
+ state2_dm = Density([state2, 1])
+ state3_dm = Density([state3, 1])
+
+ assert fidelity(state1_dm, state1_dm) == 1
+ assert fidelity(state1_dm, state2_dm) == 0
+ assert fidelity(state1_dm, state3_dm) == 1/sqrt(2)
+ assert fidelity(state3_dm, state2_dm) == 1/sqrt(2)
+
+ #using qubits/density(mixed states)
+ d1 = Density([state3, 0.70], [state4, 0.30])
+ d2 = Density([state3, 0.20], [state4, 0.80])
+ assert fidelity(d1, d1).round(3) == 1
@certik Owner
certik added a note

And the same here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@travisbot

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

@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))
+ arg1, arg2 : 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 Density, 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)
@certik Owner
certik added a note

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))
+ >>> 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 Density, 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))
+ >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
@certik Owner
certik added a note

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

@flacjacket Collaborator

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

@certik Owner
certik added a note

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

@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
@certik
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):
return -np.sum(eigvals*np.log(eigvals))
else:
raise ValueError("numpy.ndarray, scipy.sparse or sympy matrix expected")
+
+
+def fidelity(arg1, arg2):
@asmeurer Owner
asmeurer added a note

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))
+ >>> # represent turns Kets into matrices
+ >>> up_dm = represent(up * Dagger(up))
+ >>> down_dm = represent(down * Dagger(down))
+ >>> updown_dm = represent(updown * Dagger(updown))
+ >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
+ >>>
+ >>> print fidelity(up_dm, up_dm)
+ 1
+ >>> print fidelity(up_dm, down_dm) #orthogonal states
+ 0
+ >>> print fidelity(up_dm, updown_dm).evalf().round(3)
+ 0.707
+
+
+ """
+ def sqrtm(mat):
@asmeurer Owner
asmeurer added a note

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
@ellisonbg
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.

@gdevanla

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

@travisbot

This pull request fails (merged ac679d1 into 9625918).

@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))
+ >>> from sympy.physics.quantum.spin import JzKet
+ >>> from sympy.physics.quantum.density import Density, 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))
+ >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
+ >>>
+ >>> print fidelity(up_dm, up_dm)
@flacjacket 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))
+ >>> updown2 = (sqrt(3)/2 )* up + (1/2)*down
+ >>>
+ >>> print fidelity(up_dm, up_dm)
+ 1
+ >>> print fidelity(up_dm, down_dm) #orthogonal states
+ 0
+ >>> print fidelity(up_dm, updown_dm).evalf().round(3)
+ 0.707
+
+ """
+ state1 = represent(state1) if isinstance(state1, Density) else state1
+ state2 = represent(state2) if isinstance(state2, Density) else state2
+
+ if (not isinstance(state1, Matrix) or
+ not isinstance(state2, Matrix)):
+ raise ValueError("state1 and state2 must be of type density or Matrix "
@flacjacket 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))
+ >>> print fidelity(up_dm, down_dm) #orthogonal states
+ 0
+ >>> print fidelity(up_dm, updown_dm).evalf().round(3)
+ 0.707
+
+ """
+ state1 = represent(state1) if isinstance(state1, Density) else state1
+ state2 = represent(state2) if isinstance(state2, Density) else state2
+
+ if (not isinstance(state1, Matrix) or
+ not isinstance(state2, Matrix)):
+ raise ValueError("state1 and state2 must be of type density or Matrix "
+ "received type=%s for state1 and type=%s for state2" %
+ (type(state1), type(state2)))
+
+ if ( state1.shape != state2.shape and state1.rows == state2.cols):
@flacjacket 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
@flacjacket
Collaborator

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

@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.

@gdevanla

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.

@ellisonbg
Owner

OK I think we can merge this.

@ellisonbg ellisonbg merged commit 3b77c94 into from
@travisbot

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
Commits on Aug 3, 2012
  1. @gdevanla
  2. @gdevanla
  3. @gdevanla
  4. @gdevanla
Commits on Aug 4, 2012
  1. @gdevanla
Commits on Aug 6, 2012
  1. @gdevanla
Commits on Aug 9, 2012
  1. @gdevanla

    style changes

    gdevanla authored
Commits on Aug 11, 2012
  1. @gdevanla

    Cleaned up doc string

    gdevanla authored
This page is out of date. Refresh to see the latest.
View
142 examples/notebooks/fidelity.ipynb
@@ -0,0 +1,142 @@
+{
+ "metadata": {
+ "name": "fidelity"
+ },
+ "nbformat": 2,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "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",
+ "from sympy.physics.quantum.operator import *",
+ "",
+ "%load_ext sympyprinting"
+ ],
+ "language": "python",
+ "outputs": [],
+ "prompt_number": 2
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "##Fidelity using some kets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "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))",
+ "updown2 = (sqrt(3)/2 )* up + (1/2)*down",
+ "",
+ "",
+ "display_pretty(fidelity(up_dm, up_dm))",
+ "display_pretty(fidelity(up_dm, down_dm)) #orthogonal states",
+ "display_pretty(fidelity(up_dm, updown_dm).evalf())",
+ "",
+ "",
+ "# alternatively, puts Kets into Density object and compute fidelity",
+ "d1 = Density( [updown, 0.25], [updown2, 0.75])",
+ "d2 = Density( [updown, 0.75], [updown2, 0.25])",
+ "display_pretty(fidelity(d1, d2))"
+ ],
+ "language": "python",
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "text": [
+ "1"
+ ]
+ },
+ {
+ "output_type": "display_data",
+ "text": [
+ "0"
+ ]
+ },
+ {
+ "output_type": "display_data",
+ "text": [
+ "0.707106781186548"
+ ]
+ },
+ {
+ "output_type": "display_data",
+ "text": [
+ "0.817293551913876"
+ ]
+ }
+ ],
+ "prompt_number": 7
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## Fidelity on states as Qubits"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "",
+ "from sympy.physics.quantum.qubit import Qubit",
+ "state1 = Qubit('0')",
+ "state2 = Qubit('1')",
+ "state3 = (1/sqrt(2))*state1 + (1/sqrt(2))*state2",
+ "state4 = (sqrt(S(2)/3))*state1 + (1/sqrt(3))*state2",
+ "",
+ "state1_dm = Density([state1, 1])",
+ "state2_dm = Density([state2, 1])",
+ "state3_dm = Density([state3, 1])",
+ "",
+ "# mixed qubit states in density",
+ "d1 = Density([state3, 0.70], [state4, 0.30])",
+ "d2 = Density([state3, 0.20], [state4, 0.80])",
+ "",
+ "",
+ "display_pretty(fidelity(d1, d2))",
+ "",
+ ""
+ ],
+ "language": "python",
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "text": [
+ "0.996370452558227"
+ ]
+ }
+ ],
+ "prompt_number": 9
+ },
+ {
+ "cell_type": "code",
+ "collapsed": true,
+ "input": [],
+ "language": "python",
+ "outputs": []
+ }
+ ]
+ }
+ ]
+}
View
60 sympy/physics/quantum/density.py
@@ -1,10 +1,9 @@
-from sympy import Tuple, Add, Mul, Matrix, log, expand
+from sympy import Tuple, Add, Mul, Matrix, log, expand, sqrt, Rational
from sympy.core.trace import Tr
from sympy.printing.pretty.stringpict import prettyForm
from sympy.physics.quantum.dagger import Dagger
from sympy.physics.quantum.operator import HermitianOperator, OuterProduct, Operator
from sympy.physics.quantum.represent import represent
-from sympy.physics.quantum.state import KetBase
from matrixutils import numpy_ndarray, scipy_sparse_matrix, to_numpy
from sympy.physics.quantum.tensorproduct import TensorProduct, tensor_product_simp
from sympy.core.compatibility import product
@@ -254,3 +253,60 @@ def entropy(density):
return -np.sum(eigvals*np.log(eigvals))
else:
raise ValueError("numpy.ndarray, scipy.sparse or sympy matrix expected")
+
+
+def fidelity(state1, state2):
+ """ Computes the fidelity between two quantum states
+ (http://en.wikipedia.org/wiki/Fidelity_of_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 Density, 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
+
+ """
+ state1 = represent(state1) if isinstance(state1, Density) else state1
+ state2 = represent(state2) if isinstance(state2, Density) else state2
+
+ if (not isinstance(state1, Matrix) or
+ not isinstance(state2, Matrix)):
+ raise ValueError("state1 and state2 must be of type Density or Matrix "
+ "received type=%s for state1 and type=%s for state2" %
+ (type(state1), type(state2)))
+
+ if ( state1.shape != state2.shape and state1.is_square):
+ raise ValueError("The dimensions of both args should be equal and the"
+ "matrix obtained should be a square matrix")
+
+ sqrt_state1 = state1**Rational(1,2)
+ return Tr((sqrt_state1 * state2 * sqrt_state1)**Rational(1, 2)).doit()
View
81 sympy/physics/quantum/tests/test_density.py
@@ -2,7 +2,7 @@
from sympy.matrices.matrices import Matrix
from sympy.core.trace import Tr
from sympy.external import import_module
-from sympy.physics.quantum.density import Density, entropy
+from sympy.physics.quantum.density import Density, entropy, fidelity
from sympy.physics.quantum.state import Ket, Bra, TimeDepKet
from sympy.physics.quantum.qubit import Qubit
from sympy.physics.quantum.qapply import qapply
@@ -201,3 +201,82 @@ def _eval_trace(self, bra, **options):
t = Tr(d)
assert t.doit() == 1
+
+
+def test_fidelity():
+ #test with kets
+ up = JzKet(S(1)/2, S(1)/2)
+ down = JzKet(S(1)/2, -S(1)/2)
+ updown = (S(1)/sqrt(2))*up + (S(1)/sqrt(2))*down
+
+ #check with matrices
+ up_dm = represent(up * Dagger(up))
+ down_dm = represent(down * Dagger(down))
+ updown_dm = represent(updown * Dagger(updown))
+
+ assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
+ assert fidelity(up_dm, down_dm) < 1e-3
+ assert abs(fidelity(up_dm, updown_dm) - (S(1)/sqrt(2))) < 1e-3
+ assert abs(fidelity(updown_dm, down_dm) - (S(1)/sqrt(2))) < 1e-3
+
+ #check with density
+ up_dm = Density([up, 1.0])
+ down_dm = Density([down, 1.0])
+ updown_dm = Density([updown, 1.0])
+
+ assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
+ assert abs(fidelity(up_dm, down_dm)) < 1e-3
+ assert abs(fidelity(up_dm, updown_dm) - (S(1)/sqrt(2))) < 1e-3
+ assert abs(fidelity(updown_dm, down_dm) - (S(1)/sqrt(2))) < 1e-3
+
+ #check mixed states with density
+ updown2 = (sqrt(3)/2)*up + (S(1)/2)*down
+ d1 = Density([updown, 0.25], [updown2, 0.75])
+ d2 = Density([updown, 0.75], [updown2, 0.25])
+ assert abs(fidelity(d1, d2) - 0.991) < 1e-3
+ assert abs(fidelity(d2, d1) - fidelity(d1, d2)) < 1e-3
+
+
+ #using qubits/density(pure states)
+ state1 = Qubit('0')
+ state2 = Qubit('1')
+ state3 = (S(1)/sqrt(2))*state1 + (S(1)/sqrt(2))*state2
+ state4 = (sqrt(S(2)/3))*state1 + (S(1)/sqrt(3))*state2
+
+ state1_dm = Density([state1, 1])
+ state2_dm = Density([state2, 1])
+ state3_dm = Density([state3, 1])
+
+ assert fidelity(state1_dm, state1_dm) == 1
+ assert fidelity(state1_dm, state2_dm) == 0
+ assert abs(fidelity(state1_dm, state3_dm) - 1/sqrt(2)) < 1e-3
+ assert abs(fidelity(state3_dm, state2_dm) - 1/sqrt(2)) < 1e-3
+
+ #using qubits/density(mixed states)
+ d1 = Density([state3, 0.70], [state4, 0.30])
+ d2 = Density([state3, 0.20], [state4, 0.80])
+ assert abs(fidelity(d1, d1) - 1) < 1e-3
+ assert abs(fidelity(d1, d2) - 0.996) < 1e-3
+ assert abs(fidelity(d1, d2) - fidelity(d2, d1)) < 1e-3
+
+ #TODO: test for invalid arguments
+ # non-square matrix
+ mat1 = [[0, 0],
+ [0, 0],
+ [0, 0]]
+
+ mat2 = [[0, 0],
+ [0, 0]]
+ raises(ValueError, lambda: fidelity(mat1, mat2))
+
+ # unequal dimensions
+ mat1 = [[0, 0],
+ [0, 0]]
+ mat2 = [[0, 0, 0],
+ [0, 0, 0],
+ [0, 0, 0]]
+ raises(ValueError, lambda: fidelity(mat1, mat2))
+
+ # unsupported data-type
+ x, y = 1, 2 #random values that is not a matrix
+ raises(ValueError, lambda: fidelity(x, y))
Something went wrong with that request. Please try again.