Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the feature of calculating entanglement measures negativity #10134

Merged
merged 5 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions qiskit/quantum_info/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
purity,
shannon_entropy,
state_fidelity,
negativity,
)
from .synthesis import (
OneQubitEulerDecomposer,
Expand Down
1 change: 1 addition & 0 deletions qiskit/quantum_info/states/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
concurrence,
mutual_information,
entanglement_of_formation,
negativity,
)
31 changes: 31 additions & 0 deletions qiskit/quantum_info/states/measures.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,34 @@ def entanglement_of_formation(state):
conc = concurrence(state)
val = (1 + np.sqrt(1 - (conc**2))) / 2
return shannon_entropy([val, 1 - val])


def negativity(state, qargs):
r"""Calculates the negativity

The mathematical expression for negativity is given by:
.. math::
{\cal{N}}(\rho) = \frac{|| \rho^{T_A}|| - 1 }{2}

Args:
state (Statevector or DensityMatrix): a quantum state.
qargs (list): The subsystems to be transposed.

Returns:
negv (float): Negativity value of the quantum state

Raises:
QiskitError: if the input state is not a valid QuantumState.
"""

if isinstance(state, Statevector):
# If input is statevector then converting it into density matrix
state = DensityMatrix(state)
# Generating partially transposed state
state = state.partial_transpose(qargs)
# Calculating SVD
_, singular_values, _ = np.linalg.svd(state.data)
eigvals = np.sum(singular_values)
# Calculating negativity
negv = (eigvals - 1) / 2
return negv
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
features:
- |
Added a new function , :func:`negativity` that adds support for calculating
entanglement measures negativity of an quantum state.
An illustrative example for using the above function is given below:

.. code-block:
from qiskit.quantum_info.states.densitymatrix import DensityMatrix
from qiskit.quantum_info.states.statevector import Statevector
from qiskit.quantum_info import negativity
import numpy as np

# Constructing a two-qubit bell state vector
state = np.array([0, 1/np.sqrt(2), -1/np.sqrt(2), 0])
# Calculating negativity of statevector
negv = negativity(Statevector(state), [1])

# Creating the Density Matrix (DM)
rho = DensityMatrix.from_label("10+")
# Calculating negativity of DM
negv2 = negativity(rho, [0, 1])


27 changes: 27 additions & 0 deletions test/python/quantum_info/states/test_measures.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from qiskit.quantum_info import entanglement_of_formation
from qiskit.quantum_info import mutual_information
from qiskit.quantum_info.states import shannon_entropy
from qiskit.quantum_info import negativity


class TestStateMeasures(QiskitTestCase):
Expand Down Expand Up @@ -341,6 +342,32 @@ def test_mutual_information_equivalence(self):
rho = DensityMatrix(psi)
self.assertAlmostEqual(mutual_information(psi), mutual_information(rho))

def test_negativity_statevector(self):
"""Test negativity function on statevector inputs"""
# Constructing separable quantum statevector
state = Statevector([1 / np.sqrt(2), 1 / np.sqrt(2), 0, 0])
negv = negativity(state, [0])
self.assertAlmostEqual(negv, 0, places=7)
# Constructing entangled quantum statevector
state = Statevector([0, 1 / np.sqrt(2), -1 / np.sqrt(2), 0])
negv = negativity(state, [1])
self.assertAlmostEqual(negv, 0.5, places=7)

def test_negativity_density_matrix(self):
"""Test negativity function on density matrix inputs"""
# Constructing separable quantum state
rho = DensityMatrix.from_label("10+")
negv = negativity(rho, [0, 1])
self.assertAlmostEqual(negv, 0, places=7)
negv = negativity(rho, [0, 2])
self.assertAlmostEqual(negv, 0, places=7)
# Constructing entangled quantum state
rho = DensityMatrix([[0, 0, 0, 0], [0, 0.5, -0.5, 0], [0, -0.5, 0.5, 0], [0, 0, 0, 0]])
negv = negativity(rho, [0])
self.assertAlmostEqual(negv, 0.5, places=7)
negv = negativity(rho, [1])
self.assertAlmostEqual(negv, 0.5, places=7)


if __name__ == "__main__":
unittest.main()